How the Java logging should works

In this article you will find the answers for these questions:

  • how java logging works
  • what is purpose of slf4j
  • what is purpose of commons-logging
  • what is difference between log4j and slf4j
  • what is difference between logback and slf4j
  • what is difference between commons-logging and log4j
  • what is difference between commons-logging and logback
  • how to redirect jul to slf4j
  • how to redirect commons-logging to slf4j

Let’s start

To begin with, there is two main concepts in Java logging:

  • logging abstraction library (logging facade). Examples: slf4j, commons-logging
  • logging implementation library. Examples: log4j, log4j2, logback

The problem

Suppose the you’re Java library developer (let’s say it’s called our_library), not standard Java application developer. You need to have logging in your library. Suppose you have chosen log4j. Then there is consumer of our library (another developer). He depends on our_library and another one (another_library). Suppose that another_library is using logback. So developer, who uses both another_library and our_library gonna lost his mind trying to understand how to combine both log4j and logback in one application.

Solution

The solution for that problem is logging facade. Logging facade is the thing, that can redirect log events to some number of logging implementation libraries. our_library and another_library should use logging abstraction library, instead of logging implementation library. Thus, our poor developer can make the choice of logging implementation library itself. Whichever library he chooses, logging facade in our_library and another_library are gonna send logging event to it.

Java libraries should use logging facade such as slf4j. It gives the logging-library-independency ability to all developers, who gonna use such java libraries. Applications will be having slf4j as transitive dependency, and ability to choose logging library implementation themselves. It may be log4j2 or logback.

Equalizing logging facades

You may ask – what if some library using another logging facade, not slf4j? Apache’s commons-logging, for example. There is certain technology called bridge.

That’s the answer for the question: how to redirect commons-logging to slf4j.

If some library is using Apache’s commons-logging, we can redirect it to the slf4j by using bridge. Just add this to your pom.xml:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>...</version>
</dependency>

And exclude Apache’s commons-logging classes from your jar. It can be done by marking dependency as provided:

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>[1.0,)</version> <!-- excluding all versions -->
    <scope>provided</scope>
</dependency>

If you using Spring, that you also need to add exclusion to spring-boot-maven-plugin, because it gonna create another jar (after Maven’s jar):

<plugin>
    ...
    <executions>
        <execution>
            ...
            <configuration>
                ...
                <excludes>
                    <exclude>
                        <groupId>commons-logging</groupId>
                        <artifactId>commons-logging</artifactId>
                    </exclude>
                </excludes>
            </configuration>
        </execution>
    </executions>
</plugin>

How do such bridges work? slf4j bridge, which redirects log events from commons-logging to slf4j merely is jar, which contain same-name-classes as presented in commons-logging. Such classes, which are replacement for originals, performs redirection work.

That the point because of which we need to exclude original commons-logging classes.

Redirecting jul to slf4j

There is dinosaur called java.util.logging, which some library may use instead of logging facade. We may want to redirect to slf4j. We also can use bridge technology to perform that. Just add that dependency to your pom.xml:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jul-to-slf4j</artifactId>
    <version>...</version>
</dependency>

Additional thanks

Tim Biegeleisen https://stackoverflow.com/a/57882386

Telegram channel

If you still have any questions, feel free to ask me in the comments under this article or write me at promark33@gmail.com.

If I saved your day, you can support me 🤝

Leave a Reply

Your email address will not be published. Required fields are marked *