跳至主要內容

Slf4j + Log4j2 日志框架

Steven大约 2 分钟java

Apache Log4j2 是对 Log4j 的升级版本,参考了 logback 的设计并修复了一些问题。主要提升有:

  • 异常处理 —— 在 logback 中,Appender 中的异常不会被应用感知到,在 log4j2 中提供了一些异常处理机制。
  • 性能提升 —— log4j2 比较 log4j 和 logback 都有很明显的性能提升。
  • 自动重载配置 —— 参考 logback 的设置,提供自动刷新参数配置的功能。(我们在生产上可以动态修改日志级别而不需要重启应用)

官网: https://logging.apache.org/log4j/2.x/open in new window

例子:适配 Slf4j

引入依赖

<?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>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>demo-java-log</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>demo-usage-slf4j-log4j2</artifactId>

    <dependencies>
<!--        <dependency>-->
<!--            <groupId>org.slf4j</groupId>-->
<!--            <artifactId>slf4j-api</artifactId>-->
<!--        </dependency>-->
        <!-- slf4j + log4j -->
<!--        <dependency> &lt;!&ndash; 日志门面 &ndash;&gt;-->
<!--            <groupId>org.apache.logging.log4j</groupId>-->
<!--            <artifactId>log4j-api</artifactId>-->
<!--        </dependency>-->
<!--        <dependency> &lt;!&ndash; 日志实现 &ndash;&gt;-->
<!--            <groupId>org.apache.logging.log4j</groupId>-->
<!--            <artifactId>log4j-core</artifactId>-->
<!--        </dependency>-->
        <dependency> <!-- 日志适配器,包含 slf4j-api, log4j-api, log4j-core 依赖 -->
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
        </dependency>
    </dependencies>

</project>

配置(参考: linkopen in new window

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

例子:桥接 Log4j(旧版)

引入依赖:

  1. 日志依赖引入、配置
  2. 业务依赖引入、排除旧日志依赖
  3. 桥接依赖引入
依赖配置
<?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>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>demo-java-log</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>demo-usage-slf4j-log4j2-over-log4j</artifactId>

    <dependencies>
        <dependency> <!-- 日志适配器,包含 slf4j-api, log4j-api, log4j-core 依赖 -->
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
        </dependency>
        <!-- 日志框架需要放在其他依赖之前(由于日志框架的加载机制 spi),或者显示的把相关依赖排除! -->
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>demo-usage-log4j-basic</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>demo-usage-slf4j-logback</artifactId>
            <version>1.0-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

</project>

桥接前
over 2024-05-02 08:32:02.554 [main] INFO  org.example.OverTest - ---------- log4j -----------
2024-05-02 08:32:02 DEBUG org.example.Log4jService 9:Alpha doSomething debug
2024-05-02 08:32:02 INFO  org.example.Log4jService 10:Alpha doSomething info
2024-05-02 08:32:02 WARN  org.example.Log4jService 11:Alpha doSomething warn
2024-05-02 08:32:02 ERROR org.example.Log4jService 12:Alpha doSomething error
over 2024-05-02 08:32:02.596 [main] INFO  org.example.OverTest - ---------- logback -----------
over 2024-05-02 08:32:02.598 [main] INFO  org.slf4j.LoggerFactory - info
over 2024-05-02 08:32:02.598 [main] WARN  org.slf4j.LoggerFactory - warn
over 2024-05-02 08:32:02.598 [main] ERROR org.slf4j.LoggerFactory - error

log4j 旧版日志未接入;logback 日志已接入(因为都是使用 slf4j 的接口,所以可以无缝接入)