Logging is one of the most fundamental aspects of any language.
Unfortunately, Java’s in-built logging mechanism
java.util.logging (available since JDK 1.4) was not feature rich nor flexible enough for most use-cases.
The community created multiple libraries to fill in this gap.
After more than a decade, the logging ecosystem has become quite complicated with each library using its own logging mechanism. Even standard projects’ dependencies look like this.
and some conversations make no sense.
Let us try to understand how we got here.
If you are new to Java logging, refer to this article to understand its features.
log4j was most used logging library in the beginning.
Once configured, using it in the code was relatively simple.
log4j classes directly in the code results in tight coupling.
The solution to reduce this coupling was to introduce Simple Logging Facade for Java aka
a library which delegated the calls to the underlying logging implementation (eg:
logback) based on runtime binding.
Unfortunately, the community could not standardize on single facade to use.
Many Java libraries used different facades (eg:
JCL aka Jakarta Commons Logging) or in many cases direct implementations (ignoring the tight coupling problem).
This created a bigger problem.
Suppose you want to create a project and log with combination of
So far so good.
But what if you want to import a library say, Guava, and that in turn uses
How would your
logback know about that library’s logging mechanism?
Also, it is impractical to be aware of all libraries’ logging implementations and configure them separately in your project.
bridge (aka adaptor) was introduced, which would redirect all those logs called via
Problem solved. Now as long as you have the right bridge(s) for all the logging libraries
being used (directly and indirectly) in your project, all the logs will be flown/streamed
slf4j and into your final logging implementation.
slf4j has all the bridges you will ever need.
The best part of this solution is – all the bridges are bound/configured automatically at runtime. Of course, the problem of which permutation-combination to use will still require including/excluding the right bridges/facades from your pom.xml. Though framework developers do think hard to make it easy for the developers.
Hit me up in the comments for any queries or critiques.