-
-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loglevel 2.0 #119
Comments
This is really great. I've got some specific thoughts below, but generally I'm very keen on this, there's a lot of nice improvements here that we can make to iterate on feedback and improve the UX longterm. There's a couple of places where I'm not totally sold, but most of this sounds superb. The main thing I'm trying to do is ensure that loglevel continues to work out of the box for as many people as possible, even in awkward environments, not just for people keeping up to date with the nicest modern stack. On your list above:
|
Speaking of version 2.0, I meant completely abandoning obsolete environments. Backwards compatibility could be saved with the help of the loglevel/legasy submodule. This is a common practice. But I do not insist, because I understand that loglevel is widely used and breaking back compatibility is undesirable. Therefore, I realized my idea in the form of a package https://github.com/kutuluk/log-n-roll. This is a 900-byte logger with a built-in prefixer. I think this is ideal for modern applications such as SPA and PWA. But I can say with confidence that all the same thing can be implemented in loglevel. The difference is only in size. So you just need to decide which changes will improve the loglevel and make them. |
Awesome work, and ideas I hope this won't grow into YAL (yet another logger). I have't looked at the code base so far, but maybe the compatibility can also be added as a plugin? |
Implementing the support of browsers from the Stone Age, you risk yourself stuck in the Stone Age. If this is your choice, then I'm not going to challenge it. But I want to live today and look into tomorrow, instead of hanging in yesterday. My position is very strong - backward compatibility with browsers no lower than IE 11 (ES5). Ensuring compatibility below is not a library task - it's a task for https://github.com/es-shims/es5-shim. |
Yep, that sounds good to me. As in my comment above, I think IE 11 is a good & low bar nowadays, and I'm fine with only publishing a 'modern' build that supports IE11+. That's still very inclusive (IE10 is now down to 0.1% of browser usage), and users who want support back even further than that can just stick with loglevel 1.x, which will keep working fine for all sorts of super old browsers, or look at shimming etc if they really need to. A legacy build would work, but I'd rather just point people back to 1.x and keep ongoing dev simple. The main legacy bit that I would like to retain is UMD, for developers not using webpack and similar, since the stats seem to suggest that's still a significant percentage of developers. That's a cheap, easy and tiny addition though, and doesn't get involved in the core of the code - we just keep the UMD wrapper & |
It sounds delicious. My current implementation https://github.com/kutuluk/log-n-roll is fully operational in IE 11. With the help of https://github.com/developit/microbundle three ES5 builds are compiled: UMD (without noConflict), CommonJS and ESM. My opinion about noConflict(): resolving name conflicts is not a library task, it's a programmer's task. The only thing that is needed from the library is to provide a permanent name, which is occupied in the global scope. One clause in the documentation. Nothing more. I've already changed my original sketch and now it's almost finished. I propose to take it as a basis, thoroughly think through the API, implement some of the most popular plug-ins (in a simplified form I have already implemented something), test and merge into loglevel under version 2.0 without backwards compatibility. The current version of loglevel is published as loglevel@legacy and maintained separately. |
That all sounds great to me. I've opened a I'm still on the fence about |
I'd second that it'd be nice to see persisting levels disabled by default (The current behaviour is confusing as we use Alternatively, provide a clear method~
|
These ideas all sound great, from my end I don't think there's any must haves in the suggested v2 features. But I'm just evaluating the library at this point, so I'm probably missing a lot of context. My interest is more on being able to add plugins to the log system in order to have flexibility on sending logs to a server, and it looks like the current version supports that with a few plugins already (or we could write our own). What's the status of v2, doesn't look there's been much activity on that branch ... |
@pimterry Do you still have any appetite for someone picking this work up? Last time this came up in January 2023 I did not have the time or energy for it (and it wasn’t clear whether you had time to really shepherd anybody’s work on it either). I might have some time for this later in December or January. If you are interested, what are the important goals?
Are there important things not in that list? Things in that list you have specific ideas about? |
I just had a baby a couple of months ago, so I am quite busy! That said, I can probably help with shepherding things slowly through and I do still think many improvements here would be worthwhile. Of your list above:
Other thoughts:
|
👍 My feel on the core ideas that make Loglevel what it is and that we don’t want to break are:
Whoa, I hadn’t realized it was still supported in any form! 😅 FWIW, caniuse is showing 0.37%, but I think that’s out of date — their data comes from statcounter.io, which is showing 0.09% for November 2024 (CSV) (the last date that had 0.37% was January 2022, so my guess here is that caniuse stopped updating IE numbers when general support was discontinued in 2022, and 0.37% was the high mark for that year). Anyway, I agree that’s not nothing, although it’s at < 0.1% and getting lower every couple months. Happy to go with whatever you decide here. (Interesting side note: I was hoping to dismiss it entirely by seeing all the usage come from US/Europe, where it probably represents old enterprise apps that aren’t going to upgrade any Loglevel version they might be using, but no, it is coming exclusively from Iran, Turkmenistan, and …Liechtenstein (!), which are not so easily ignorable).
I definitely hear you on wanting to minimize churn from tooling. But I think this is always going to be an issue since the level of compatibility you are shooting for is just way beyond what the JS community as a whole is worried about. This development note on compatibility will probably always be necessary. In particular, I don’t think we can escape:
It’s probably possible to replace a lot of the existing Grunt stuff with bash. Otherwise, I’m not sure it’s possible to get more minimal than we are now after #194 and #195. For types in particular, I’ve maintained packages that build their types from JSDoc comments and ones where the actual source is TypeScript. If this is going to essentially be a rewrite, I would tend towards writing in in TypeScript, but that does tend to add to the dev tooling complexity. So JSDoc comments might be better in that regard. Either way, I would recommend against continuing to hand-roll the type definitions.
I think we probably want to try and avoid that (at least as much as is reasonably possible), since it drives us right back to this tooling churn issue.
I was thinking we definitely still want built-in support for loading dynamic configuration of some sort — I can understand how that’s not “core,” but it still seems like a pretty basic and common need. If I want to flip on more detailed debugging while investigating a shipping version of a website or app (or filing an issue/support ticket), it’s really nice to be able to just do that without having thought ahead to add an extra plugin or custom code of your own (assuming you are the app’s author; this isn’t an option for you otherwise). And insofar as the places we’re loading from are writable (e.g. localstorage or cookies and not env vars or querystrings), it would make sense to build in the corresponding write support. Alternatively, maybe built-in support only includes sources that are non-writable, e.g. env vars or URL querystring/hash? That sidesteps the saving/writing issues.
I think there are a lot of open questions here! And there’s already a lot to think about in all the above stuff. Maybe best to leave this to plugins to patch in for now, and it’s something that could be addressed in a later 2.x release? |
I think we're on the same page here 👍
Let's try aiming to support IE11 then, but stay open to dropping it if something turns out to be particularly difficult/inconvenient. I'm hopefully it'll be OK.
That's ok! Yes, my main concern isn't the current state - in the message above I was really trying to set context for future decisions, as we consider tooling we might want to include. There are some small changes we could make: I'd be happy to replace Grunt with small scripts, but it's not critical, just nice to tidy up. I think using TypeScript and other fairly mature tools is fine (unless we do very complex things, TS should keep working as-is with low churn for a long time). I just want to make sure we don't integrate new tools to solve problems as part of v2 that then create extra maintenance going forwards.
I think in fact it's not so bad! If we say we're happy with TypeScript, tsc can do this for us with no other tools involved. We just set the compile target, e.g. we could build with For multiple bundles, we would have a couple of different
Yeah, this is interesting and needs thought, you're right, and it needs thought before the first release, since it's pretty fundamental and could be breaking. My main concern is that everybody will want something different, and we don't want to support everything. Accepting external changes from storage at runtime is significantly harder than external config at startup - we'd need to monitor localStorage for changes for example, but then exclude our own changes from that, and then you have to think about multiple tabs sharing this state... Gets messy. Allowing env/URL-based config is easier, but then brings back 3rd option, we could allow runtime changes via an explicit a global API, like All interesting, but needs thought.
Just an idea really. It is a bit easier than it sounds, since it seems modern runtimes have generally standardized the console API, but would need investigation. Doing this in plugins would be a bit unusual, since most other existing plugins are all focused on internal processing, not changing the external API very much. Not a breaking change to add later though, so yes I'm happy to punt for now, just food for thought. Where would you want to start? I think we could break this up into steps, and build the core library + drop old bits (old compat, persistence) + set up export/bundle formats (and test their compatibility) now, while thinking further about the plugin & dynamic config parts that need more design work separately. |
Congratulations! Love this lil library.
Be aware that zsh and fish are also popular with some people. Perhaps look into a Makefile (so that you have a single interface that then could adapt to different shells). |
Thanks!
True - but these would be shell scripts, not complex commands you need to run, so they're independent of the default shell you use. If we put a That said, makefiles are very common and extremely stable and fairly convenient for most people I think. Let's see how it goes, and even if even need to migrate from Grunt at all - if we decide we do, and then we end up with quite a complicated script setup, |
Sorry I was MIA for a few days…
I definitely don’t have time until probably late next week at the earliest, but I think what you’re suggesting makes sense (excepting maybe dropping persistence, since I feel like the question is still open about what we do and don’t want, see below). When you say “old compat,” do you have specific things in mind? Based on this discussion, I think the clearly droppable things are:
With that and separate ESM/UMD builds, we could start releasing Do you want to recreate a fresh
Obviously I was not very clear! I just meant loading at startup (I probably should have said “runtime config” or “user config”). I agree live updating is much more complicated and not really necessary (or at least can be a plug-in). This is not a path I meant to send you down.
What I meant here is that I think it might be OK to ignore this problem. IIRC I “invented” the concern that method was trying to address when I added it, and I am concerned I may have overinflated its value vs. the cognitive complexity it invites. (Another way to support this but that might be more clear is an initialization option, e.g.
Personally, I don’t think this shortcut really adds anything valuable over what’s already available.
This is true, but a lot of these are stateful, and I think impose questions with non-obvious answers when it comes to multiple loggers. @Ryuno-Ki I think @pimterry already covered what I would have said re: zsh/fish/etc. 🙂 |
Yes, I agree with all of those, the only other notable part to lose is
Both now done 👍 Console APIs
This is a good point! There's interesting solutions we could explore but yes multiple loggers do make it quite a bit more complicated. If there's any easy wins then we can consider including them, but happy to totally ignore anything non-trivial for v2.0.0. PersistenceI think the runtime model is still interesting (controlling logs from debuggers/dev consoles is genuinely useful) but wouldn't be a breaking change to add later, so lets park that. Changing the initialization logic later would be a breaking change though, so we need a plan for that up front. For default levels, I do think there's a question here worth addressing... The problem is if the application developer (we can ignore libraries here I hope/assume) calls In that scenario, presumably the intent is to override that One option is that we just ignore all setLevel calls for the affected logger (but not other loggers, assuming we're going to use support some kind of logger-targeting syntax like DEBUG etc do). In effect, if you provide an external input, that forces the level of the given logger(s) indefinitely. Does that work? Seems like a reasonable & simple solution if the UX is OK. |
OK, I filed a first step PR that drops special IE handling we no longer need in #203. It doesn’t try and change syntax, build tooling, module handling, or anything else yet. I’ll probably try and tackle separate ESM & UMD builds (and maybe TypeScript) next in a separate PR, since there are a lot more decisions and things to be done there.
Thanks!
That works, but then I feel like it makes What I was thinking with my last idea about // my-script.js
import { getLogger } from 'loglevel';
// Provide the default level as an option rather than getting the logger and calling `setDefaultLevel()`.
// No changes from today about how `setLevel()` behaves.
const myLogger = getLogger('myLogger', { level: 'error' });
// Rest of app code...
myLogger.warn('Some warn message'); So you get no logs normally: > node my-script.js But can override at runtime as usual: > LOGLEVEL_MYLOGGER=info node my-script.js
Some warn message But, TBH, this whole conversation is making me feel like I’m overly worried about all this, and the current interplay between |
For the naming, could we switch to @loglevel/loglevel for the primary loglevel, but also publish a version as just "loglevel" for backwards compatibility? |
If I recall correctly there is a policy on it. As in, publish a final |
@wayfarer3130 @Ryuno-Ki I'm open to publishing separate-but-related packages as I assume your concern with intentionally using v1 in new and existing apps after v2 is published? That will be relevant for codebases that don't want the churn of updates or who do need the very old IE version support we're dropping. That won't be a problem though - there will be no issue with using v1 if you want to after v2 is published, in either existing or new codebases, even if the package name is the same. It would be possible to deprecate individual versions of the package (i.e. all v1 versions of |
Loglevel is good. It's time to make it fresh. More clearly. More modern.
log.getLogger('child')
=>log('child')
Implementation loglevel.js
Example
Output
If this fits into the development concept of loglevel, I will make a pull request
The text was updated successfully, but these errors were encountered: