[slf4j-user] Recommendation for library writers: use thiscopy and paste wrapper around SLF4j to avoid default static initialization

Joachim Durchholz jo at durchholz.org
Sat Mar 18 22:57:24 CET 2017


Am 18.03.2017 um 20:04 schrieb Adam Gent:
> I generally agree with your points but I also know there are plenty of
> people that completely disagree.
> Just check out https://bill.burkecentral.com/2012/05/22/write-your-own-logging-abstraction/

That post motivates writing yet another SLF4J replacement to get rid of 
both SLF4J and whatever backends are being used, reinventing the SLF4J 
wheel.
He's writing a logger facade to end all logger facades - 
https://xkcd.com/927/ comes to mind.

Or maybe he's writing his own logger library. In which case all the 
3rd-party libraries he's using are still happily logging to whatever 
(now left-unconfigured) backend they always have been logging to.

> This would be an effort to some what mitigate those who have concerns
> have SLF4J and its depenency.

The post actually focuses on dependency hell.
Except it's no hell with SLF4J - newer versions are generally 
API-compatible with older versions, so you simply use the newest version 
of SLF4J.
And you use whatever backend you want, be it JUL, commons logging, 
log4j, or even logback - SLF4J can talk to all of them, in whatever 
version you're throwing at it.

> I also wonder if your general opinion isn't stockholm syndrom.

Nope.
In fact I dislike a few things about SLF4J, but they are different from 
your pain points.
My impression is that you're working off some very basic 
misunderstanding of how SLF4J works, but I can't put my finger on it. 
I've been trying to sort that out, but whenever I explain something, you 
continue with a totally unrelated topic and one message later you still 
stick with the idea I tried to explain away two messages ago. It's a bit 
frustrating, and I may give up on that - maybe somebody else has more luck.

 > Do you have any idea how many people hate:
>
> SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
> SLF4J: Defaulting to no-operation (NOP) logger implementation
> SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for
> further details.

Yeah I hated that, too.

> As a library writer it is fairly annoying to have to deal with users
> complaining about.

WTF?
If I'm an application writer, I visit the URL given, read that all I 
need to do is to explicitly add a backend adapter to the class path, 
then I do it.
If I'm a library writer and application writers come to me complaining, 
I tell them to Read The Friendly Error Message and buzz off.

Really. It's SLF4J telling you you misconfigured it, and it's going to 
do its best but please fix that.
Maybe SLF4J should mark this as a WARNING so people don't get scared if 
they see "failed to load class", though the second line of text actually 
tells you what's going on.

I hated seeing that message, but the fix was just a dependency in the 
main application's(!) dependencies (you don't add it to a library, nope, 
no, never - it could be used as a scope=test dependency but that's about 
it).

>> How would the library know whether it's called in Android?
>> Should it even care?
>
> Yes. The reality is often it has to. Maybe not the code itself but the
> library maintainers might have to be concerned with Android (this
> includes backporting at times).

If the code does not have to care, then it shouldn't configure the 
logging backend.

> Of course if you don't care about Android...

Oh I do.

>> Your proposal does not change anything about the performance of trace
>> messages.
>
> Yes it does! I have benchmarked it myself... but alas I don't feel
> like pulling JMH out now nor the hassle of dealing with Android to
> prove such.

Benchmarking is notoriously tricky, and it is very, very easy to measure 
something totally different than what you think.
So to make sure that your claim is based on actual performance, you need 
to have somebody independent double-check your test code and your 
measurements.

 > Unless you are extremely careful about configuration or
> just always globally using the NOPLogger there is generally some
> overhead the logging framework will do per call.

Since the noop looger does nothing, it's pretty impossible to have extra 
overhead.

 > Now I admit this is a
> while ago and I can't remember what logging framework was underneath.
> Maybe logback does a better job. I can't imagine it some how has
> specially loggers for each level (or maybe it does).

As I already explained elsewhere, it has just a small three-field 
configuration object per "logger".
Initialization and configuration are done just once, anything else would 
be madness.

>> That's a solved problem: SLF4J is collecting log messages during startup,
>> and emitting them once the backend is ready.
>
> That doesn't fix anything. I have to now figure out how to intercept
> the backend before it does whatever you know like connecting to a
> message queue.

Why do you still need to do that?

> Really... I don't think you realize how successful you guys have been
> in getting everyone to use SL4J.

That's unrelated - logging has been a thing long before even Java 
entered the scene.
It's just that with Java, writing servers became commonplace, and since 
you can't usefully run a debugger on a server, logging is your substitute.

> Application startup time is a big deal... it is the number one hate of
> Java I hear most.

Yeah, but SLF4J is pretty innocent.
Swing is pretty slow to start, so interactive software used to take a 
looong time to start up.
Plus with Hotspot (i.e. the JVM that's standard everywhere except 
Android), any application starts fully interpreted, has the JIT compiler 
eat CPU cycles in the background, and only after a while it becomes fast.

> But you missed my point that most library consumers (applications)
> really just don't give crap about what their libraries are logging.
> And when they really really do they can go to the libraries web site
> and figure out how to turn on logging. I mean you have to figure out
> the logger names anyway.

Yeah, but my point is that the library shouldn't try to set an 
application-wide policy. It shouldn't even set a logging policy for 
itself, because it cannot know what context it is running in.

> My point was I only care about the parent framework and my
> applications codes logging. It seems a shame to have innocuous
> libraries  instantiating 1-3 different libraries indirectly (depending
> on how many wrappers, bridges, and converters you are using). It is
> just the kind of thing people complain about Java.

Actually SLF4J cuts down on that: you have only one backend, not three.
This also means you have only one configuration, so startup becomes faster.

> All in all I was *trying* to improve the adoption of SLF4J and have it
> handle more than 80/20 but 100 of most use cases.

I'm still waiting to see one of those 20% cases...


More information about the slf4j-user mailing list