Introduction to SLF4J – SLF4J简介

最后修改: 2016年 10月 12日

1. Overview

1.概述

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中添加以下库。

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.7</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.7</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.7</version>
</dependency>

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:

让我们看看如何创建Logger实例。

public class SLF4JExample {

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

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

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

注意,LoggerLoggerFactory属于org.slf4j包。

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.

我们不需要将SLF4J添加到我们的classpath中来使用它和Logback,因为Logback已经在使用SLF4J。它是参考实现。

So, we just need to include the Logback library:

因此,我们只需要包括Logback库。

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

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

最新的版本可以在这里找到。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.

该配置是针对Logback的,但与SLF4J的工作是无缝的。有了适当的依赖关系和配置,我们可以使用前面几节的相同代码来处理日志。

4. The Log4j Setup

4.Log4j设置

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.

我们可以将SLF4J配置为一个桥梁,将对现有框架的调用重定向到它。

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

让我们添加必要的依赖项,为Log4j创建一个桥。

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

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

有了这个依赖关系(在log4j-over-slf4j上查看最新情况),对Log4j的所有调用将被重定向到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.

就像其他框架一样,Log4j可以作为一个底层实现。

Let’s add the necessary dependencies:

让我们添加必要的依赖性。

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.30</version>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

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

下面是slf4j-log4j12log4j的最新版本。以这种方式配置的示例项目可在这里获得。

5. JCL Bridge Setup

5.JCL桥接设置

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.

JCL旨在作为一个类似于SLF4J的框架。主要的区别是,JCL在运行时通过一个类加载系统来解决底层实现。在有自定义类加载器发挥作用的情况下,这种方法似乎有问题。

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

SLF4J在编译时解决了它的绑定问题。它被认为是更简单但足够强大。

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

幸运的是,两个框架可以在桥梁模式下一起工作。

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

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

最新的依赖性版本可以在这里找到。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

6.进一步的SLF4J特性

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

SLF4J提供了额外的功能,可以使记录更有效,代码更可读。

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

例如,SLF4J为处理参数提供了一个非常有用的界面。

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

Here is the Log4j code doing the same thing:

下面是做同样事情的Log4j代码。

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.

我们可以看到,无论debug级别是否启用,Log4j都会连接Strings。在高负荷应用中,这可能会导致性能问题。另一方面,SLF4J只有在启用debug级别时才会连接Strings

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

为了对Log4J做同样的事情,我们需要添加一个额外的if块,它将检查debug级别是否被启用。

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.

SLF4J规范了日志级别,这些级别对于特定的实现来说是不同的。它放弃了FATAL日志级别(在Log4j中引入),其前提是在一个日志框架中我们不应该决定何时终止一个应用程序。

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

7.结论

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

SLF4J有助于在日志框架之间进行无声的切换。它很简单,但很灵活,并允许可读性和性能改进。

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.

像往常一样,可以在GitHub上找到代码。此外,我们还参考了另外两个致力于不同文章但包含所讨论的日志配置的项目,可以在这里这里找到它们。