理解日志框架
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