Introduction to SLF4J – SLF4J简介

最后修改: 2016年 10月 12日


1. Overview


Simple Logging Facade for Java (abbreviated SLF4J) acts as a facade for different logging frameworks (e.g., java.util.logging, logback, Log4j). It offers a generic API, making the logging independent of the actual implementation.

Simple Logging Facade for Java(缩写为SLF4J)作为不同的日志框架(例如,java.util.logging、logback、Log4j)的一个facade>。它提供了一个通用的API,使日志记录独立于实际实现。

This allows for different logging frameworks to coexist. And it helps migrate from one framework to another. Finally, apart from standardized API, it also offers some “syntactic sugar.”

这使得不同的日志框架可以共存。而且它有助于从一个框架迁移到另一个框架。最后,除了标准化的API,它还提供一些 “语法糖”。

This tutorial will discuss the dependencies and configuration needed to integrate SLF4J with Log4j, Logback, Log4j 2 and Jakarta Commons Logging.

本教程将讨论将SLF4J与Log4j、Logback、Log4j 2和Jakarta Commons Logging集成所需的依赖和配置。

For more information on each of these implementations, check out our article Introduction to Java Logging.

有关这些实现的更多信息,请查看我们的文章Java Logging 介绍

2. The Log4j 2 Setup

2. Log4j 2的设置

To use SLF4J with Log4j 2, we add the following libraries to pom.xml:

为了在Log4j 2中使用SLF4J,我们在pom.xml中添加以下库。


The latest version can be found here: log4j-api, log4j-core, log4j-slf4j-impl.

最新的版本可以在这里找到。log4j-api, log4j-core, log4j-slf4j-impl

The actual logging configuration adheres to native Log4j 2 configuration.

实际的日志配置遵守本地Log4j 2的配置。

Let’s see how to create the Logger instance:


public class SLF4JExample {

    private static Logger logger = LoggerFactory.getLogger(SLF4JExample.class);

    public static void main(String[] args) {
        logger.debug("Debug log message");"Info log message");
        logger.error("Error log message");

Note that the Logger and LoggerFactory belong to the org.slf4j package.


An example of a project running with this configuration is available here.


3. The Logback Setup

3. 日志回溯设置

We don’t need to add SLF4J to our classpath to use it with Logback since Logback is already using SLF4J. It’s the reference implementation.


So, we just need to include the Logback library:



The latest version can be found here: logback-classic.


The configuration is Logback-specific but works seamlessly with SLF4J. With the proper dependencies and configuration in place, we can use the same code from previous sections to handle the logging.


4. The Log4j Setup


In the previous sections, we covered a use case where SLF4J “sits” on top of the particular logging implementation. Used like this, it completely abstracts away the underlying framework.

在前面的章节中,我们介绍了一个用例,即SLF4J “坐 “在特定的日志实现之上。像这样使用,它完全抽象出了底层框架。

There are cases when we cannot replace existing logging solution, e.g., due to third-party requirements. But this does not restrict the project to only the already used framework.


We can configure SLF4J as a bridge and redirect the calls to an existing framework to it.


Let’s add the necessary dependencies to create a bridge for Log4j:



With the dependency in place (check for latest at log4j-over-slf4j), all the calls to Log4j will be redirected to SLF4J.


Take a look at the official documentation to learn more about bridging existing frameworks.


Just as with the other frameworks, Log4j can serve as an underlying implementation.


Let’s add the necessary dependencies:



Here are the latest versions for slf4j-log4j12 and log4j. An example project configured this way is available here.


5. JCL Bridge Setup


In the previous sections, we showed how to use the same codebase to support logging using different implementations. While this is the main promise and strength of SLF4J, it is also the goal behind JCL (Jakarta Commons Logging or Apache Commons Logging).

在前面的章节中,我们展示了如何使用同一个代码库来支持使用不同实现的日志。虽然这是SLF4J的主要承诺和优势,但这也是JCL(Jakarta Commons Logging或Apache Commons Logging)的目标。

JCL is intended as a framework similar to SLF4J. The major difference is that JCL resolves the underlying implementation during runtime through a class loading system. This approach can seem problematic in cases where there are custom class loaders at play.


SLF4J resolves its bindings at compile time. It’s perceived as simpler yet powerful enough.


Luckily, two frameworks can work together in the bridge mode:



The latest dependency version can be found here: jcl-over-slf4j.


As with the other cases, the same codebase will run just fine. An example of a complete project running this setup is available here.


6. Further SLF4J Features


SLF4J provides additional features that can make logging more efficient and code more readable.


For example, SLF4J provides a very useful interface for working with parameters:


String variable = "Hello John";
logger.debug("Printing variable value: {}", variable);

Here is the Log4j code doing the same thing:


String variable = "Hello John";
logger.debug("Printing variable value: " + variable);

As we can see, Log4j will concatenate Strings whether debug level is enabled or not. In high-load applications, this may cause performance issues. On the other hand, SLF4J will concatenate Strings only when the debug level is enabled.


To do the same with Log4J, we need to add an extra if block, which will check if debug level is enabled:


String variable = "Hello John";
if (logger.isDebugEnabled()) {
    logger.debug("Printing variable value: " + variable);

SLF4J standardized the logging levels, which are different for the particular implementations. It drops the FATAL logging level (introduced in Log4j) based on the premise that in a logging framework we should not decide when to terminate an application.


The logging levels used are ERROR, WARN, INFO, DEBUG and TRACE. Read more about using them in our Introduction to Java Logging.

使用的日志级别是ERRORWARNINFODEBUGTRACE。在我们的Java 日志介绍中阅读有关使用它们的更多信息。

7. Conclusion


SLF4J helps with the silent switching between logging frameworks. It is simple, yet flexible, and allows for readability and performance improvements.


As usual, the code can be found over on GitHub. In addition, we reference two other projects dedicated to different articles but that contain the discussed log configurations, which can be found here and here.