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

Ceki Gülcü ceki at qos.ch
Sat Mar 18 20:45:32 CET 2017



On 3/18/2017 20:04, Adam Gent wrote:

[snip]

> I also wonder if your general opinion isn't stockholm syndrom. 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.

That's just a warning message. SLF4J could drop that warning. The user 
would be oblivious to why logging is not working but otherwise things 
would just be ticking.

> As a library writer it is fairly annoying to have to deal with users
> complaining about. The ones that really care about logging are
> generally OK with dealing with extra step

Logging needs to be set up somehow. SLF4J has adopted the most stupid 
approach imaginable for selecting the logging backend. The main 
advantage of this stupid approach is that it is easy to understand to 
anyone interested.

>> In that case, my recommendation is: Just use SLF4J as it comes out of the
>> box. (I have yet to see a different recommendation.)
>>
>>> Particularly if this library is high performance or maybe used by
>>> android applications. In such case the library would default to the
>>> NOPLogger and thus not initialize.

There is a little android related optimization in 
org.slf4j.LoggerFactory during initialization which was introduced a few 
months back.

>>
>> 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).
> Of course if you don't care about Android...
>
>
>> 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. 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. 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).

I somehow doubt that. NOPLogger does nothing, so invoking it costs a 
method call. Getting a NOPLogger involves reading the value of 
INITIALIZATION_STATE which is a volatile int. Unless reading volatile 
variables is expensive in Android, there is really no way to optimize 
logging with SLF4J+NOPLogger.

>> 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 think you need your own interception? In multi-threaded 
boot-up process, SLF4J event replay just works. It's an internal process 
transparent to user code. In a single threaded boot-up, event replay 
works just as well. The interception is done by SLF4J while the logging 
back end is configuring itself and the intercepted events are replayed 
after the logging backed has finished configuring itself.

--
Ceki


More information about the slf4j-user mailing list