<Klogging logging library> version 0.5.10 has been...
# feed
m
Klogging logging library version 0.5.10 has been released. Recent updates include: • Implementation of JDK Platform Logging using Klogging • Logging calls can include a map of items • Load custom rendering and sending code from DSL or file configuration • Bugfixes, including for loading HOCON configuration files Full documentation at https://klogging.io
K 5
s
It’s only for JVM and JS, right? To be honest I feel that we need less logging libraries, not more. 👀 Clog even gave up and recommended Kermit in an consolidation attempt. I still want an official JetBrains logging framework or at least an slf4j equivalent coming with the standard lib. My libs don’t include any logging right now, because there are so many libs and I can’t decide for users which one. Would it be an Java lib I would just go for slf4j, but there is no slf4k
m
Only JVM at this stage. I have not seen another Kotlin library that natively uses Kotlin coroutine scopes to manage contextual information. That will be possible on all platforms with coroutines, when implemented.
s
I don’t say that Kermit is better. In fact I don’t have an overview over the different libs. Your lib might bring something new to table. It’s just that by now there are so many and I wished we could consolidate on one lib. One lib that eventually may be adopted by JetBrains and eventually become kotlinx-logging. Somehow it’s overdue as I don’t see the one go-to solution for Kotlin Multiplatform logging.
6
Couldn’t you add the new features of your lib to Kermit? Or is Kermit noch a good base? I actually don’t use it, it’s just the name I hear the most when it comes to logging. In my app I use expect/actuals because I can’t decide on one and had troubles running Kermit two years ago.
https://github.com/terrakok/kmp-awesome?tab=readme-ov-file#-log This is what I mean. And your lib as well as two others I know of are even missing.
😮 1
Someone needs to put up a comparison chart to help me choose. 😅
m
This discussion pops up every once in a while for a long time now. While the Java ecosystem has recognised and solved this issue already many years ago, the mobile world does not even seem to understand the problem. This is kind of astonishing and frustrating at the same time. A similar reasoning applies to the topic of dependency injection.
👍 1
s
d
We're migrating from Timber to Kermit at work. It's actually still an Android-only project right now but we're instating a policy of 'keeping the door open to multi-platform' so that as a team we can be ready if the business needs us to pivot the technology. Just 'keeping the door open' isn't expensive really, it's rarely 'more work' just 'doing things a bit differently'.
1
s
Yes, indeed, I would do the same. If I had the choice between two projects, I would always choose the one that supports more platforms, even if the current project state won't need it. This is one way of future proofing.
plus1 2
r
@Michael Strasser As the primary author of Log4j Kotlin, I'm not sure why your README says:
These libraries (mostly) wrap underlying Java libraries and suffer from the same limitations.
Log4j Kotlin supports coroutine based logging context just like klogging. Log4j also supports structured logging via the JSON layout, and uses nanotime for log events, so I don't think it suffers from any of the limitations you listed. Thoughts?
👀 1
r
@Stefan Oltmann It is indeed JVM-only at the moment, just like klogging is.
s
Doesn’t matter for an API, does it?
r
Right, it should be relatively easy to replace the backend in future and make it multi-platform
s
In the Java world we failed to agree on a logger implementation, too. But we succeeded in agreeing on one API which is slf4j. Agreeing on one API for logging is the very first step.
r
Agreeing on one API makes sense for libraries, but doesn't really matter for end-users
s
Craft a slf4k which is just a bunch of interfaces like slf4j as an independent project and implement those in slf4j Kotlin. Then send Kermit a PR to implement them too.
I don’t know what you mean with „end users“. You are confusing me. 👀
r
Sorry, "end users" is confusing. I mean developers building applications, as opposed to developers building libraries.
If I'm building an application, it doesn't matter what API I use, as long as I pick one. For library authors, we don't know which logging implementation our users will want, so we need to use something like slf4j so that our logs end up in the right place regardless.
s
Yes, developers building applications will need to decide on a concrete logger implementation of course, but they can also make most of the code logger implementation agnostic. This is the case with slf4j. But of course library authors benefit the most.
r
Sure its implementation agnostic, but which API is largely irrelevant. For example, see https://logging.apache.org/log4j/2.x/manual/api-separation.html.
s
That’s why I wrote this morning that my libraries use no logging at all, because there is no slf4k. I can’t make them logger implementation agnostic
We are on the same page here. So my proposal is to make a slf4k which would be just slf4j converted to Kotlin.
Even regular Java log4j could implement it using the JVM targeted artifacts of that
Bring the power of slf4j to Kotlin 😄
I would do it myself if I were not so invested in bringing image metadata libraries to the ecosystem. I can’t do everything. 😁
You could do it and you are in a good position to do it.
r
There are a few challenges, which is why I think this hasn't been done yet: • slf4j only has to deal with the JVM -- figuring out at runtime what implementation we want to use just had to be implemented once for the JVM -- a true "slf4k" needs to take into account every possible platform target, and where the capabilities of implementations on each platform drive API to some extent (markers, structured logging, etc.) • I'm not sure there is no widespread agreement yet on what an slf4k API would look like in Kotlin -- there is the usual java APIs converted to Kotlin (basically using lambdas for message construction instead of parameterized strings), but there are lots of other good API ideas out there, see Google's flogger for example. • Users of slf4j still only had to configure one JVM backend i.e. one
log4j.xml
or
logback.xml
or what have you -- users of a true multi-platform slf4k still have to configure every platform's underlying logging
s
Agreed. Slf4k would need a logic like that for every Kotlin Multiplatform target. For the second point I would just start with a 1:1 translation from slf4j, not inventing something new.
r
I think where things will tend to go in the Kotlin world in the future is a compiler plugin (once the compiler plugin API is stable!) where the plugin can implement a lot of useful functionality like cheap location awareness.
s
Not so sure about that. I would prefer to implement a small slf4k lib containing very few interfaces.
New API ideas is something that some might like and others might not. So it’s risky. For a de facto standard like slf4j you are not that picky, because it’s the standard. You just go with it.
And as it has been established and is known to many a slf4k that is a slf4j drop in replacement on the JVM will have a very high acceptance. Promised.
r
The "magic" in slf4j is not in the API, but in its runtime backend selection. The APIs already exist, see kotlin-logging, logging-log4j-kotlin, klogging, kflogger, kermit, and more. There is actually even an slf4k already existing (though it still uses slf4j under the hood, so its JVM only). Maybe the "slf4j" for the Kotlin world is just a standard way to inject lambdas into libraries for logging. I don't know .
The logging library with compiler plugin support would still have some kind of defined API -- the plugin may just help with things like compile-time injection of location and backend integration.
Anyway, lots of things to think about 🙂 I'm guessing the community will standardize on something over time, just as happened with slf4j.
s
You could be the driver for that, Raman. That’s what I’m talking about. 😄
r
And as it has been established and is known to many a slf4k that is a slf4j drop in replacement on the JVM will have a very high acceptance. Promised.
Not sure about this. The proliferation you see in kotlin logging frameworks is all on the API side. They all use the same backends as usual -- on the JVM log4j2 or logback, etc.
You could be the driver for that, Raman. That’s what I’m talking about. 😄
I know that's what you're saying but I don't think so. The process of competing frameworks being invented and being experimented with in the wild needs to happen first.
s
The APIs already exist, see kotlin-logging, logging-log4j-kotlin, klogging, kflogger, kermit, and more.
That’s not what I meant. These are logger implementations, each with its own API. Like every library has an API. I’m talking about THE logging api. This does NOT exist for Kotlin. Slf4j is THE logging API in the Java world.
r
I know, see above -- my point is slf4j succeeded because its API was basically very similar to the existing APIs out there (log4j2, logback, classic log4j, jul.logging) -- and so people didn't care about the API, they just wanted to make sure all their logs ended up in the same place. That agreement on API hasn't happened in the Kotlin world yet.
s
🤔 So you say Kermit and the others are just APIs like slf4j? I was thinking these are all logger implementations like log4j
r
Yes
s
Interesting. As I said I’m not into the logging libs too much. So all of them use log4j on the JVM?
r
Yes, pretty much, or or logback or they wrap slf4j (which in turn uses log4j, logback, etc.), yes. Kermit doesn't provide a JVM implementation as far as I know writes to standard output on the JVM, it uses the native loggers on JS, Android, and iOS. logging-log4j-kotlin is an API but currently with only log4j2 as an implementation.
s
Ok, so the problem is not that we have to many logger implementations, but that we can’t decidece on how a slf4k should look like (more like Java or more idiomatic Kotlin, etc) and therefore have too many options of that.
r
Right
Plus different platform focus: kermit focuses on mobile, for example.
s
Yeah, libs that don’t target all KMP targets are not interesting at all. I wouldn’t consider using klogging at all until it does not target every platform.
I believe if you offer a Kotlin lib that operates on such a base level like logging and DI it needs to target all platforms to have any chance of success.
In my book the „Kotlin is just a nicer language for the JVM“ days are over.
💯 3
m
@rocketraman Thanks for raising the coroutine capabilities in Log4j Kotlin. I will update the Klogging README to be more accurate. I have used Log4j, including JSON layouts and high-precision timestamps. (I used it in a Kotlin Spring Boot project in preference to Logback, which is less capable.) The coroutine-based logging context in Log4j Kotlin is not the same as Klogging. Klogging has a
LogContext
class that is like both
ContextMap
and
CoroutineThreadContext
in Log4j Kotlin. It has a complete set of
suspend
logging functions to call within coroutine scopes that include any items from the log context (it can also include information from SLF4J MDC and other contexts if wanted). Klogging also uses coroutines to process log events asynchronously.
r
@Michael Strasser > Klogging has a LogContext class that is like both ContextMap and CoroutineThreadContext in Log4j Kotlin. Ok — the API might be slightly different but not massively so, and the functionality seems the same. > It has a complete set of suspend logging functions to call Hmm — interesting that klogging's API uses suspend functions. Not sure that appeals to me. Enabled logging is I/O bound and I'm assuming users are not expected to wrap every logging call in
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
, so that means klogging has no choice but to do the actual logging I/O async non-blocking WRT the logging API cal. And if that's the case, then why incur the cost of having logging calls be suspending? > Klogging also uses coroutines to process log events asynchronously. Interesting and nice as a library author, but for a user, its an implementation detail. Unlike something like say Ktor where the use of coroutines is fundamental to the user's API surface.
👀 1