Java logging libraries explained

When looking at the various Java-based logging libraries, it’s hard to see the forest through the trees. SLF4j, Log4j, Logback, what’s the difference? What’s this strange log4j-slf4j-impl library doing in my stack? And why does this library keep logging in Log4j format while I’ve configured Logback? You can find answers to all these questions in this guide. Note that I won’t cover all logging libraries, but just the most common ones.


Log4j is the oldest logging stack of them all. It comes in a set of two dependencies, one being the interface and the other being the implementation. You can use this logging stack of two dependencies standalone in your application. Your code uses the Log4j API and the Log4j-core library does the work.

standard Log4j stack

SLF4J & Logback

What is the difference between SLF4J and Logback/Log4j?

The original author of Log4j 1.x (latest version is 2.x) created a successor which became Logback, a new logging library implementation. SLF4J (Simple Logging Facade for Java) on the other hand, is purely an interface/API, which is implemented by Logback. Your code uses the SLF4J API and the Logback library does the work. If you only include the slf4j-api dependency in your project, without an implementation such as Logback, all your log calls will end up nowhere (no-op).

standard Logback stack

This stack is perfect when you don’t use libraries with a dependency on Log4j. However, if you do, then I recommend using the Log4j to SLF4J stack mentioned later in this article. It also uses SLF4j as the API and Logback as the implementation, but it also makes sure that the Log4j-based logs of your libraries also end up going through your SLF4j-Logback stack.

SLF4J to Log4j

Can we use Log4j and SLF4J together?

Yes, you can, which brings us to another logging stack, which is a combination of SLF4J as the API and Log4j as the implementation. To achieve this, you need to use the log4j-slf4j-impl library, which provides a bridge between the SLF4J API and the Log4j 2 API. Your code will use the SLF4J API and the log4j-core dependency provides the logging implementation.

slf4j to log4j stack

Log4j to SLF4J

The inverse of the previous stack. The log4j-over-slf4j binding library captures all Log4j calls and routes them to the SLF4J API. It’s primarily a stack to migrate applications coded against the Log4J API to the SLF4J API and then use a different logging implementation, such as Logback.

log4j to slf4j stack

Help: I’ve configured this stack, but it keeps logging with log4j instead of using my new Logback configuration!

When using this stack, it is important to remove the Log4j dependency from your project and also exclude it from any other library dependency that is trying to pull it in. Otherwise, the remaining Log4j library will take over and your logs won’t be routed to the SLF4J API.

In December 2021, a major Log4j vulnerability in all versions prior to or equal version 2.14 shook the world of JVM-based app deployments. Luckily, the Log4j team patched this vulnerability quickly, but every project using this old version still had to apply the newest version. One alternative option for application maintainers, instead of upgrading to the newest Log4j library, could’ve been to apply this log4j-over-slf4j stack, which essentially removes the Log4j dependency altogether.

One last word of caution when using this logging stack is that you should never combine the log4j-over-slf4j library with the log4j-slf4j-impl library, as it will cause a loop, causing your logs to end up nowhere.

Actionable career advice,
in your inbox

Advance your career as a software engineer by regularly receiving my 15+ years of experience in your email inbox.

new advice & strategies to advance your career 🎓

exclusive content, not available on the site 🚀

updates on existing articles, with new insights! 💫

product updates and special offers 💥

    Unsubscribe at any time.