[slf4j-user] Fail Silently on NOP implementation

Marshall Pierce marshall at mpierce.org
Thu Apr 28 13:35:23 UTC 2016


The job of slf4j-api is just to be the developer-side interface to logging. It purposely delegates the decision of what to do with those logs to the end user. I think it is a mistake to include policy mechanisms like these into the API. 

If you’re writing a library, don’t include a binding. If you’re writing a tool, select a binding. It is an error to not include a binding, and that’s why it prints to stderr. If you’re writing a tool and you want silence, use nop. If you’re not writing a tool, it’s not your decision.

Regarding slf4j-silent / slf4j-strict: This is just another “policy via classpath” mechanism. If you want to control the output of calls made via slf4j-api, we already have a mechanism for this. What happens when both are on the classpath? As a new user to SLF4J, would you really enjoy learning how to use dependency excludes as a debugging tool during your “why won’t my logging show up” journey rather than having a clear error message that informs you that you’re doing it wrong, and pointing you towards the URL with more info? This complicates logging, and the debugging thereof, without a clear gain.

The fundamental issue is that you’re trying to use the same artifact as both a library and an end-user tool (which I’ll define as “a thing with a main method or equivalent”). This is an antipattern because there are conflicting goals for libraries and tools, as you’ve correctly identified. If your users will consume your code in two different ways, then it is sensible to have two different artifacts.

-Marshall

> On Apr 27, 2016, at 3:23 PM, Phillip Lord <phillip.lord at russet.org.uk> wrote:
> 
> Steven Schlansker <sschlansker at opentable.com> writes:
> 
>>> On Apr 27, 2016, at 1:00 AM, Phillip Lord <phillip.lord at russet.org.uk> wrote:
>>> 
>>> 
>>> 
>>> The currently implementation of SLF4J prints a message on usage of the
>>> NOP implementation. This is not very friendly at all, as it means that
>>> if any dependency of my project includes a a dependency on SLF4J, I
>>> suddenly get an error message whether I wish it or not.
>> 
>> Wow, you run Java apps without wanting slf4j logging?  Who even does that
>> nowadays? ;)
> 
> Not wishing to be rude, but I'd never heard of slf4j till it started
> print messages out to me. Not the greatest introduction, although it
> seems like a nice thing otherwise!
> 
> Actually, I'm using the JVM rather than Java per se. I'm also writing a
> piece of software that is an "end-user" tool (so, should include a slf4j
> binding) and is usable as a library (so, should not include a slf4j
> binding).
> 
> 
>>> This could be implemented in a number of ways -- you could make a
>>> slf4j-api-with-noisy dependency, you could look for an environment
>>> variable, or a system property. Users who need the warning would get it,
>>> and end-users who are not using slf4j explicitly would be untroubled by
>>> its presence,
>> 
>> I suspect that changing the default behavior is out of the question, at
>> least until a 2.x.x major release.  Additionally, some of the pushback
>> I received with the earlier approach was about the difficulty of managing
>> and lack of visibility associated with system properties.
> 
> System properties are, indeed, a disaster. And using them to specify a
> binding never works well. That's why I suggested several options. You'd
> probably need all of them.
> 
> None of this is for defining the binding -- it's simple to enable the
> "you've got no bindings" message (and probably the "you've got >1
> bindings" message also).
> 
> 
>> So how about this:
>> 
>> slf4j-api retains current behavior.  Log if nop / duplicate
>> implementation.
> 
> It doesn't "log" -- it dumps a message to standard error. If it was
> logging, I could turn it off!
> 
> 
>> -> Introduce a "slf4j-silent" jar which modifies the slf4j logger binding
>>   process to be silent
>> 
>> -> Introduce a "slf4j-strict" jar which modifies the slf4j logger binding
>>   process to fail explosively on any trivial misconfiguration
>> 
>> This probably only requires a single hook inside of the LoggerFactory,
>> same way you hook StaticLoggerBinder there could be a
>> StaticLoggerBindingConfiguration which is provided by one of these jars
>> (or silently absent, in the "default" case)
> 
> This would seem reasonable -- assuming these are maven dependencies as
> well as jars. Another possibility would which works like -nop (i.e.
> shuts up the "no bindings" message), but does not cause the multiple
> bindings error message (i.e. it gives way silently).
> 
> 
>> Then, assuming the end user has good control of their build process, they
>> can elect to introduce one or the other (Personally, I would include
>> "slf4j-strict" in our default Maven parent POM globally)
> 
> I don't understand the idea of the "end user" in this sense. Some one
> has to make the decision about what to do for an implementation. In
> fact, slf4j-api DOES make this decision (i.e. it nops), if no one else
> does. Should I make the decision for my library? Or should I leave it
> downstream project? Some of them are mine, but some are not.
> 
> 
>> The biggest downside is you wanted a "no additional configuration necessary"
>> solution, but I don't think that is possible -- the default case is already
>> defined and likely won't change.
> 
> I think I could easily convince the upstream project which has
> introduced the slf4j-api dependency to switch to an
> slf4j-api-and-silent-nop. At the moment, they are not so happy about
> adding a slf4j-nop dependency directly, because it trades the certainty
> of one error message, for the risk of another. I think this is a good
> trade, but a solution which does not have this risk would be nicer.
> 
>> Would this approach be welcome by the developers?  Would it solve your
>> problem satisfactorily, even though it's not 100% what you wanted?
> 
> If I have understood your suggestion correctly, yes, I think it would
> help.
> 
> Thanks for the reply.
> 
> Phil
> _______________________________________________
> slf4j-user mailing list
> slf4j-user at qos.ch
> http://mailman.qos.ch/mailman/listinfo/slf4j-user



More information about the slf4j-user mailing list