Bootstrap

Java - 日志体系_Simple Logging Facade for Java (SLF4J)日志门面_SLF4J集成Log4j2.x 及 原理分析

在这里插入图片描述


官网

https://slf4j.org/

在这里插入图片描述

Simple Logging Facade for Java (SLF4J) 用作各种日志记录框架(e.g. java.util.logging、logback、log4j)的简单外观或抽象,允许最终用户在部署时插入所需的日志记录框架 时间。

请注意,启用 SLF4J 的库意味着仅添加一个强制依赖项,即 slf4j-api.jar。 如果在类路径上找不到绑定/提供程序,则 SLF4J 将 default 为 no-operation 实现。


SLF4J user manual:https://slf4j.org/manual.html

在这里插入图片描述


集成步骤

在这里插入图片描述

POM依赖

为了实现 SLF4J 与 Log4j 2.x 的集成,您需要添加以下 Maven 依赖:

<!-- slf4j -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.12</version>
</dependency>

<!-- log4j2 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.2</version>
</dependency>

<!-- log4j-slf4j-impl -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.2</version>
</dependency>
  • slf4j-api: SLF4J 的核心 API,用于定义日志接口。
  • log4j-apilog4j-core: Log4j 2.x 的核心库,提供日志记录功能。
  • log4j-slf4j-impl: Log4j 2 与 SLF4J 的适配器,用于将 SLF4J 的日志调用转发给 Log4j 2。

在这里插入图片描述

使用案例

第一步:编写 Log4j2 的配置文件

创建一个 log4j2.xml 配置文件,设置 Log4j 2 的日志级别和输出格式。

 <?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} %-5p %c{1}:%L --->>> %m%n"/>
        </Console>

        <!-- 文件输出 -->
        <RollingFile name="RollingFile" fileName="logs/app.log"
                     filePattern="logs/app-%d{yyyy-MM-dd}.log">
            <PatternLayout>
                <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n</pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy/>
            </Policies>
        </RollingFile>
    </Appenders>

    <Loggers>
        <!-- 根日志级别设置为info -->
        <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>

 

第二步:在代码中使用 SLF4J

在代码中通过 LoggerFactory.getLogger() 获取日志记录器实例,并使用 SLF4J API 记录日志。

package com.artisan;


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

/**
 * slf4j 与 log4j2 集成
 *
 */
public class Slf4jLog4j2Example {

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

    public static void main(String[] args){
        logger.trace("Slf4jLog4j2Example This is a trace message");
        logger.debug("Slf4jLog4j2Example This is a debug message");
        logger.info("Slf4jLog4j2Example This is an info message");
        logger.warn("Slf4jLog4j2Example This is a warning message");
        logger.error("Slf4jLog4j2Example This is an error message");
    }
}
 

在这里插入图片描述

原理分析

1. 获取对应的 ILoggerFactory

SLF4J 通过 StaticLoggerBinder 类来绑定日志实现。在 log4j-slf4j-impl 包中,StaticLoggerBinder 是关键类,它返回 Log4jLoggerFactory,这是 Log4j 2.x 集成的核心。

  • 步骤 1.1:SLF4J 使用类加载器加载 org/slf4j/impl/StaticLoggerBinder.class,找到 log4j-slf4j-impl 包中的绑定类。
  • 步骤 1.2:创建 StaticLoggerBinder 实例后,通过 getSingleton() 获取 ILoggerFactory,该工厂返回 Log4jLoggerFactory 实例。
StaticLoggerBinder.getSingleton().getLoggerFactory(); // 获取 Log4jLoggerFactory 实例

2. 根据 ILoggerFactory 获取 Logger 实例

Log4jLoggerFactory 实现了 SLF4J 的 ILoggerFactory 接口,并负责根据名称返回 Logger 实例。具体步骤如下:

@Override
protected Logger newLogger(final String name, final LoggerContext context) {
    final String key = Logger.ROOT_LOGGER_NAME.equals(name) ? LogManager.ROOT_LOGGER_NAME : name;
    return new Log4jLogger(context.getLogger(key), name);
}

@Override
protected LoggerContext getContext() {
    final Class<?> anchor = ReflectionUtil.getCallerClass(FQCN, PACKAGE);
    return anchor == null ? LogManager.getContext() : getContext(ReflectionUtil.getCallerClass(anchor));
}
  • 步骤 2.1:通过 Log4j 2 的 LoggerContext 获取 Logger 实例,这与 Log4j 2 的原生方式一致。
  • 步骤 2.2:将 org.apache.logging.log4j.core.Logger 封装成 SLF4J 的 Logger 接口实现(即 Log4jLogger),从而实现 SLF4J 的日志调用。

3. 日志记录过程

当调用 SLF4J 的日志方法时(如 logger.debug()),日志请求会被传递到 Log4jLogger,并最终委托给 Log4j 2.x 的原生 Logger 实例进行处理。Log4j 2 会根据配置文件(如 log4j2.xml)进行日志输出。

小结

  • 依赖关系:通过 slf4j-apilog4j-apilog4j-corelog4j-slf4j-impl 实现 SLF4J 与 Log4j 2.x 的集成。
  • 核心过程:SLF4J 通过 StaticLoggerBinder 类绑定到 Log4j 2,Log4jLoggerFactory 创建 Logger 实例,最终通过 Log4jLogger 封装 Log4j 2 的 Logger
  • 日志调用转发:SLF4J 的日志调用会被转发到 Log4j 2 进行实际的日志记录,并根据 log4j2.xml 配置输出日志。

在这里插入图片描述

;