共计 2214 个字符,预计需要花费 6 分钟才能阅读完成。
理解日志框架
Java 日志框架:slf4j 作用及其实现原理
Java 日志零碎历史从入门到解体
常见的日志产品
SLF4j 框架通过扫描 classpath 上面的 org/slf4j/impl/StaticLoggerBinder.class 类来发现日志产品 jar,个别用到的日志 jar 有 logback、log4j2。如下是是 SLF4j 框架对接各个日志产品的依赖。
- slf4j-api 是 SLF4j 的框架 API
- logback 和 slf4j-simple 都是间接实现 SLF4j 框架的接口
- log4j 不是间接实现 SLF4j 接口,因而须要一个桥接 jar,即 slf4j-log4j12
- log4j2 和 logj 相似,也须要一个桥接的 jar,即 log4j-slf4j-impl,留神这个 jar 和 log4j 不一样。此外 log4j2 自身由两个 jar 组成,即 log4j-api 和 log4j-core
<dependencies>
<!-- slf4j api-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!-- slf4j logback implement-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- slf4j simple implement-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
<!-- slf4j adapter for log4j start-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- slf4j adapter for log4j end-->
<!-- slf4j adapter for log4j2 start-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.1</version>
</dependency>
<!-- slf4j adapter for log4j2 end-->
</dependencies>
SLF4J 如何进行 SPI
SPI 的全称是 Service Provider Interface,是 Java 提供的可用于第三方实现和扩大的机制,通过该机制,咱们能够实现解耦,SPI 接口方负责定义和提供默认实现,SPI 调用方能够按需扩大。
个别 classpath 下只有一种日志实现,个别罕用 logback 或 log4j2, 如果 classpath 有多个日志实现,会怎么?SLF4j 到底会抉择哪一个?
如果有多个日志实现,SLF4j 会打印日志,通知使用者以后有多个日志实现 jar,并且显示以后应用的是哪个,如下图,classpath 下有 logback,slf4j-simple,log4j,log4j2 4 个日志实现;并且 binding 应用 logback。
咱们走读源码,也看不出来到底在哪个中央抉择 logback。实际上,日志 logback 的抉择不是通过代码来管制的,应该是通过 java 类加载机制来确定的,因为 4 个日志实现都蕴含同一个类 org.slf4j.impl.StaticLoggerBinder.class,而 jvm 对于同一个类,只会加载一次,加载到哪个日志实现的 StaticLoggerBinder 就用那个日志实现。
SLF4j 通过类加载来实现 SPI 发现日志产品。这种 SPI 办法很奇妙,奇异。
日志跟踪相干
MDC(Mapped Diagnostic Context,映射调试上下文)是 Slf4j(提供了接口定义和外围实现,日志库负责适配器的实现) 提供的一种不便在多线程条件下记录日志的性能。
log4j2 的 ThreadContext