API分离

选择日志库时,必须小心谨慎,以确保正确考虑多个不同的日志库。

例如,您依赖的库代码可能使用 slf4j,而其他库可能只使用 java.util.logging。 所有这些都可以路由到 log4j 核心以便记录。

但是,如果您想使用不同的日志记录实现(例如 logback),则可以将消息从 Log4j API 路由到 logback,确保您的应用程序不依赖于特定的日志记录框架。

使用 Log4j2 API 的典型类如下所示:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Log4j2Test {
    private static final Logger logger = LogManager.getLogger();

    public Log4j2Test(){
        logger.info( "Hello World!" );
    }
}

为了使用 Log4j2 的 API 部分,我们只需要提供一个依赖项 log4j-api。

使用 Maven,您可以将以下内容添加到您的依赖项中:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.0</version>
</dependency>

使用 Log4j2 API 和核心

一起使用 Log4j2 API 和实现(核心)意味着日志消息将通过 Log4j2 核心进行路由。

Log4j2 核心实现负责以下内容(注意:这不是一个详尽的列表):

系统配置(例如通过 XML 文件) 将消息路由到 Appender 打开文件和其他资源进行日志记录(例如网络套接字) 手册中的配置页面描述了Log4j2核心实现支持的配置格式。

要同时使用 API 和核心实现,您需要将以下内容添加到您的依赖项中(假设您使用的是 Maven):

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.0</version>
</dependency>

将 Log4j2 API 与 Logback 结合使用

由于 Log4j2 API 是通用的,我们可以使用它通过 SLF4J 发送消息,然后让 Logback 对消息进行实际记录。

这意味着您可以编写绑定到 Log4j2 API 的代码,但是如果您的代码用户已经在使用 Logback,则他们不需要使用 Log4j2 核心。

要切换到使用 Logback 作为您的日志记录后端,您需要将以下内容添加到您的依赖项中(假设您使用的是 Maven):

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-to-slf4j</artifactId>
    <version>2.17.0</version>
</dependency>
<dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.10</version>
</dependency>

使用 Log4j2 作为 SLF4J 实现

如果您不想依赖 Log4j2 API 而想使用 SLF4J,那也是可能的。

假设我们的代码如下所示:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Log4j2Test {

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

    public Log4j2Test(){
        logger.info( "Hello World!" );
    }
}

然后我们可以使用 log4j-slf4j-impl 将消息路由到 Log4j2,如下所示:

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

将 Log4j2 与 JUL 结合使用

也可以将使用 java.util.logging 记录的消息路由到 Log4j2。 假设代码如下所示:

import java.util.logging.Logger;

public class Log4j2Test {

    private static final Logger logger = Logger.getLogger(Log4j2Test.class.getName());

    public Log4j2Test() {
        logger.info("Hello World!");
    }
}

然后,我们还可以通过添加 JUL 桥并将这些消息路由到 Log4j2 核心,并在 JVM 上设置 -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager(请参阅 JUL 上的文档 适配器以获取有关其工作原理的更多信息)。

为了将这些消息路由到 Log4j2,您的依赖项将如下所示:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-jul</artifactId>
    <version>2.17.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.0</version>
</dependency>

使用 Log4j2 作为 Log4j1 的后端

某些软件可能仍然依赖于Log4j1,在某些情况下修改此软件以将其迁移到Log4j2 可能是不可行的。

但是,可以在不修改应用程序的情况下开始使用 Log4j2。

假设我们的代码如下所示:

import org.apache.log4j.Logger;

public class Log4j2Test {

    private static final Logger logger = Logger.getLogger(Log4j2Test.class);

    public Log4j2Test(){
        logger.info( "Hello World!" );
    }
}

然后,我们可以根据 log4j-1.2-api 桥快速轻松地配置这些消息以使用 Log4j2 作为日志记录实现,如下所示:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-1.2-api</artifactId>
    <version>2.17.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.0</version>
</dependency>

参考资料

https://logging.apache.org/log4j/2.x/manual/api-separation.html