11.10.13

Simplifying the distinction between SL4J and commons logging




This is why everyone uses SLF4J nowadays :)


Here is how you track down and update your SLF4J Logging:

First, scan the classpath for slf4j bindings.

Then, make sure there is only one such binding.

Finally, when you find what binding is being used:  Consult the specific configuration for it.

On the other hand - Here's how tracking commons logging works: 

First you have to find HOW the log binding is being implemented.

 - Check if the org.apache.commons.logging.log property is set in commons-logging.properties or by your application through the Commons Logging API.

 - If not, check for log4j on the classpath, or else, if you have the JDKLogger (JDK 1.4+), or finally, if the simple logger is being used (when no other logger is available, thats the default for commons logging).

- Then, consult the configuration specifics of your logging configuration.

Compile-time binding versus Runtime binding

When I first read about compile-time binding, it seemed dubious:  How can a java library which can log using different frameworks rely on compile time binding?  The answer is  that the "compile-time" binding only refers to the fact that SLF4J is *compiled* against an implementation of an SLF4J logger... However, you can still use a different binding at runtime. 

SLF4J doesn't use classloaders, instead, its very simple:  It loads org.slf4j.impl.StaticLoggerBinder.  Each implementation of SLF4J (i.e. the slf4j-log4j bindings) provides a class with this exact name.... So there is no confusion.  At run-time, the same thing happens: The class is picked up from the classpath directly, without any runtime magic.  What if no slf4j-* implementations are on the classpath?  Well... then no logging will occur.   

Sometimes magic is good.  Other times, its annoying.  

The only way you can ever determine if the magic available in your application is worthwhile is after the fact.  So I think commons-logging was a really important experiment: It demonstrated that relying on explicit bindings which can be implemented in many different ways doesn't work well in the java community.

The lessons learned from the complexity of the commons-logging API have gave way to the much simpler, more explicit, and equally dynamic methodology: SLF4J.

What makes SLF4J so much better?  To be honest, its probably that modern java developers are very effective at dependency management, because they generally use maven to manage dependencies.

Thus, the pure JAR binding strategy of SLF4J is super easy to implement (due to modern java dependency management tools).

Probably 10 years ago, before java dependency management problems had been solved, commons-logging was a simpler, quick-and-dirty way to ensure that your application could log dynamically without too much configuration overhead.


TL;DR?

use SLF4J for your logging and manage your java dependencies properly

6 comments:

  1. Thanks ceki. I see the link on http://slf4j.org/ :)

    ReplyDelete
  2. Thanks Jay for such a nice and concise explanation. Above you have mentioned SLF4J supports run time binding also. Can you please explain it?

    ReplyDelete
  3. sl4j can be used in ATG applications ?

    ReplyDelete