JAVA 日志框架

前言

程序的日志记录是必不可少的, 这里做简单的描述与总结. 总体而言, 日志框架分为三部分:

  1. 门面: 类似接口, 也称 门面型日志框架
  2. 桥接: 通常用于🔗连接门面 与 实现, 也适用于重定向, 比如第三方库内部使用了 JUL, 我们使用 jul-to-slf4j 将其日志流重定向到 slf4j 门面上
  3. 实现: 记录型日志框架

在实际引用中, 为了扩展与安全, 我们通常使用上述的三个组合, 不直接使用实现, 另外见 🐛什么是Log4j 漏洞?

记录型日志框架

  1. JUL: JDK1.4 以来的 java.util.logging 下的包 👌
  2. Log4j: Apache 下的一个过期实现 👎
  3. Log4j2: 同 Log4j, 但不兼容 1 👌
  4. Logback: 与 Slf4j 同一个作者, Spring 的默认(建议使用) 👍

门面型日志框架

  1. JCL: Apache 所属, 也称 Commons Logging
  2. SLF4J: 简易门面(Simple Logging Facade for Java)

我不想考虑那么多, 直接给我配置就行

OK, 下边是一个可选的组合

  1. 添加 SLF4J
  2. 添加 Logback
  3. (可选): 如果第三方库使用了 JCL 加入 jcl-over-slf4j
  4. (可选): 如果第三方库使用了 JUL 加入 jul-to-slf4j , 在入口类时桥接
  5. (可选): 如果第三方库使用了 log4j1 , 移除 log4j1 加入 log4j-over-slf4j
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    <dependencies>
<!--选择的项目 门面 👍-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.12</version>
</dependency>
<!--选择的项目 实现 👍-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.3</version>
</dependency>

<!--重定向 JCL ✍️-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>2.0.12</version>
</dependency>
<!--被覆盖的 JCL 门面 👋-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.3.0</version>
</dependency>

<!--重定向 JUL ✍️-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>2.0.12</version>
</dependency>

<!--重定向 log4j1 ✍️-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>2.0.12</version>
</dependency>
<!--移除 log4j1 依赖 ❌-->
<!-- <dependency>-->
<!-- <groupId>log4j</groupId>-->
<!-- <artifactId>log4j</artifactId>-->
<!-- <version>1.2.17</version>-->
<!-- </dependency>-->
</dependencies>

桥接代码:

1
2
3
4
private static void BridgeJulToSLF4() {
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
}

具体的执行图: legacy.png

参考