“SLF4J 日志桥接器”的版本间的差异

来自姬鸿昌的知识库
跳到导航 跳到搜索
第21行: 第21行:
  
 
=== 示例 通过使用桥接器把依赖的底层 Log4j 替换为 Slf4j + Logback ===
 
=== 示例 通过使用桥接器把依赖的底层 Log4j 替换为 Slf4j + Logback ===
 +
要使用桥接器把依赖的底层 Log4j 替换为 Slf4j + Logback,需要做两件事:
 +
 +
# 取消对 Log4j 的依赖
 +
# 引入对 SLF4J 和 SLF4J 桥接器(对于 Log4j 来说是 log4j-over-slf4j)的依赖
 +
# 引入对 Logback 的依赖
 +
 +
==== pom.xml ====
 +
<syntaxhighlight lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<project xmlns="http://maven.apache.org/POM/4.0.0"
 +
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 +
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 +
    <modelVersion>4.0.0</modelVersion>
 +
 +
    <groupId>io.github.jihch</groupId>
 +
    <artifactId>slf4j-demo</artifactId>
 +
    <version>1.0-SNAPSHOT</version>
 +
 +
    <properties>
 +
        <maven.compiler.source>8</maven.compiler.source>
 +
        <maven.compiler.target>8</maven.compiler.target>
 +
    </properties>
 +
 +
    <dependencies>
 +
 +
        <!-- 原先对 Log4j 的依赖 -->
 +
<!--        <dependency>-->
 +
<!--            <groupId>log4j</groupId>-->
 +
<!--            <artifactId>log4j</artifactId>-->
 +
<!--            <version>1.2.17</version>-->
 +
<!--        </dependency>-->
 +
 +
        <!-- slf4j 日志门面 -->
 +
        <dependency>
 +
            <groupId>org.slf4j</groupId>
 +
            <artifactId>slf4j-api</artifactId>
 +
            <version>1.7.27</version>
 +
        </dependency>
 +
 +
        <!-- Logback 日志实现 -->
 +
        <dependency>
 +
            <groupId>ch.qos.logback</groupId>
 +
            <artifactId>logback-classic</artifactId>
 +
            <version>1.2.3</version>
 +
        </dependency>
 +
 +
        <!-- 配置 Log4j 的桥接器 -->
 +
        <dependency>
 +
            <groupId>org.slf4j</groupId>
 +
            <artifactId>log4j-over-slf4j</artifactId>
 +
            <version>1.7.25</version>
 +
        </dependency>
 +
 +
        <dependency>
 +
            <groupId>junit</groupId>
 +
            <artifactId>junit</artifactId>
 +
            <version>4.12</version>
 +
        </dependency>
 +
 +
    </dependencies>
 +
 +
</project>
 +
</syntaxhighlight>
 +
 +
==== Log4jTest.java ====
 +
<syntaxhighlight lang="java">
 +
import org.apache.log4j.Logger;
 +
import org.junit.Test;
 +
 +
public class Log4jTest {
 +
 +
    // 定义 Log4j 日志记录器
 +
    public static final Logger LOGGER = Logger.getLogger(Log4jTest.class);
 +
 +
    // 测试桥接器
 +
    @Test
 +
    public void test() {
 +
        LOGGER.info("hello Log4j");
 +
    }
 +
}
 +
</syntaxhighlight>原先调用 Log4j 的代码不需要作出任何改变<syntaxhighlight lang="console">
 +
10:15:37.606 [main] INFO io.github.jihch.Log4jTest - hello Log4j
 +
</syntaxhighlight>
 +
 +
==== 注意问题 ====
 +
 +
# jcl-over-slf4j.jar 和 slf4j-jcl.jar 不能同时部署。前一个 jar 文件将导致 JCL 将日志系统的选择委托给 SLF4J,后一个 jar 文件将导致 SLF4J 将日志系统的选择委托给 JCL,从而导致<u>无限循环</u>。
 +
# log4j-over-slf4j.jar 和 slf4j-log4j12.jar 不能同时出现
 +
# jul-to-slf4j.jar 和 slf4j-jdk14.jar 不能同时出现
 +
# 所有的桥接都只对 Logger 日志记录器对象有效,如果程序中调用了内部的配置类或者是 Appender,Filter 等对象,将无法产生效果。

2023年2月27日 (一) 02:24的版本

https://www.bilibili.com/video/BV1iJ411H74S?p=25

通常,您依赖的某些组件依赖于 SLF4J 以外的日志记录 API。

您也可以假设这些组件在不久的将来不会切换到 SLF4J。

为了解决这种情况,SLF4J 附带了几个桥接模块,这些模块将对 log4j,JCL 和 java.util.logging API 的调用重定向,就好像它们是对 SLF4J API 一样。


桥接解决的是项目中日志的遗留问题,当系统中存在之前的日志 API,可以通过桥接转换到 slf4j 的实现

  1. 先去除之前老的日志框架的依赖
  2. 添加 SLF4J 提供的桥接组件
  3. 为项目添加 SLF4J 的具体实现

https://www.slf4j.org/legacy.html

SLF4J 日志桥接器1.png



示例 通过使用桥接器把依赖的底层 Log4j 替换为 Slf4j + Logback

要使用桥接器把依赖的底层 Log4j 替换为 Slf4j + Logback,需要做两件事:

  1. 取消对 Log4j 的依赖
  2. 引入对 SLF4J 和 SLF4J 桥接器(对于 Log4j 来说是 log4j-over-slf4j)的依赖
  3. 引入对 Logback 的依赖

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>io.github.jihch</groupId>
    <artifactId>slf4j-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>

        <!-- 原先对 Log4j 的依赖 -->
<!--        <dependency>-->
<!--            <groupId>log4j</groupId>-->
<!--            <artifactId>log4j</artifactId>-->
<!--            <version>1.2.17</version>-->
<!--        </dependency>-->

        <!-- slf4j 日志门面 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.27</version>
        </dependency>

        <!-- Logback 日志实现 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

        <!-- 配置 Log4j 的桥接器 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.25</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

    </dependencies>

</project>

Log4jTest.java

import org.apache.log4j.Logger;
import org.junit.Test;

public class Log4jTest {

    // 定义 Log4j 日志记录器
    public static final Logger LOGGER = Logger.getLogger(Log4jTest.class);

    // 测试桥接器
    @Test
    public void test() {
        LOGGER.info("hello Log4j");
    }
}

原先调用 Log4j 的代码不需要作出任何改变

10:15:37.606 [main] INFO io.github.jihch.Log4jTest - hello Log4j

注意问题

  1. jcl-over-slf4j.jar 和 slf4j-jcl.jar 不能同时部署。前一个 jar 文件将导致 JCL 将日志系统的选择委托给 SLF4J,后一个 jar 文件将导致 SLF4J 将日志系统的选择委托给 JCL,从而导致无限循环
  2. log4j-over-slf4j.jar 和 slf4j-log4j12.jar 不能同时出现
  3. jul-to-slf4j.jar 和 slf4j-jdk14.jar 不能同时出现
  4. 所有的桥接都只对 Logger 日志记录器对象有效,如果程序中调用了内部的配置类或者是 Appender,Filter 等对象,将无法产生效果。