官网文档 | 官方地址

Slf4j 入门

使用 slf4j 内置的简单的实现

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<!--slf4j简单日志实现-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.26</version>
</dependency>

slf4j 相比于JCL 只提供了5个日志级别,去除了fatal

1
2
3
4
5
6
7
8
9
10
11
12
public class Slf4jTest {
private static final Logger logger = LoggerFactory.getLogger(Slf4jTest.class);

@Test
public void testQuick(){
logger.error("error");
logger.warn("warning");
logger.info("info"); // slf4j-simple 默认日志级别 简单的日志框架的都是这个
logger.debug("debug"); // 复杂的日志框架都是这个,logback log4j
logger.trace("trace");
}
}

输出形式

1
2
3
4
5
6
logger.info("用户:{}{}", "李扬", 1);
try {
int i = 10 / 0;
} catch (Exception e) {
logger.error("出现异常", e);
}

日志绑定

本质上就是依靠slf4j进行日志门面的同意管理

  • 蓝色部分代表默认遵循了slf4j的规范可以直接进行使用
  • 青色部分代表了适配层,需要引入桥接进行使用

image.png

  • slf4j-nop 代表了日志的开关,如果引入这个包,代表日志不在进行使用,全部禁用;
  • 适配层的包,默认会将上下两层的包全部导入,例如slf4j-log412.jar,默认依赖了slf4j和log4j;
  • 直接实现的包,默认也直接依赖了slf4j;

    推荐:直接引入处于第三层的包(红色边框)就可以完全导入所有依赖。

绑定流程:

  1. 添加slf4j-api的依赖
  2. 使用slf4j的API在项目中进行统一的日志记录
  3. 绑定具体的日志实现框架(其实默认就已经引入了slf4j的依赖)
    1. 绑定已经实现了slf4j的日志框架,直接添加对应依赖
    2. 绑定没有实现slf4j的日志框架,先添加日志的适配器,再添加实现类的依赖
  4. slf4j有且仅有一个日志实现框架的绑定(如果出现多个默认使用第一个依赖日志实现)

绑定原理流程

org.slf4j.LoggerFactory#getLogger(java.lang.String)
org.slf4j.LoggerFactory#getILoggerFactory()
org.slf4j.LoggerFactory#performInitialization()
org.slf4j.LoggerFactory#bind()
org.slf4j.LoggerFactory#findPossibleStaticLoggerBinderPathSet() 其中的STATIC_LOGGER_BINDER_PATH=“org/slf4j/impl/StaticLoggerBinder.class”,只要实现这个方法就可以完成绑定操作。

桥接原理

桥接和绑定不同,绑定适用于前期的选型问题,确定下来就已经定死了,桥接适用于一些老代码的日志切换为Slf4j进行管理。不会改变原有的代码格式。桥接解决的是项目中日志的遗留问题,当系统中存在之前的日志API,可以通过桥接转换到slf4j的实现。

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

image.png

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.26</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.8</version>
</dependency>

注意问题:

  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等对象,将无法产生效果。