一. 日志体系分类
1.1 功能分类
- 门面类
- slf4j:Simple Logging Facade for Java,为java提供的简单日志Facade
- 具体实现类
- logback
- log4j1
- log4j2
- jul:Java.Util.Logging
- simple
- nop
- jcl:Jekarta Commons Logging
1.2 jar包分类
类别 | jar包名 | 说明 | ||
---|---|---|---|---|
门面类 | slf4j-api | slf4j的门面 | ||
适配器类 | log4j-1.2-api | log4j1—>log4j2 | ||
log4j-jcl | commons-logging到log4j的桥梁 | |||
jcl-over-slf4j | commons-logging 到slf4j的桥梁 | |||
slf4j-jdk14 | slf4j到jdklog的桥梁,Jdk原生日志框架 | |||
slf4j-jcl | slf4j到commons-logging的桥梁 | |||
logback-slf4j | slf4j到logback的桥梁 | |||
jul-to-slf4j | jul-java.util.logging到slf4j的桥梁 | |||
jcl-over-slf4j | commons-logging 到slf4j的桥梁 | |||
log4j-over-slf4j | log4j到slf4j的桥梁 | |||
slf4j-log4j12 | slf4j到log4j1的桥梁 | |||
log4j-slf4j-impl | slf4j到log4j2的桥梁 | |||
实现类(以log4j2为例) | log4j-api、log4j-core | log4j2日志的核心实现包
|
二. 以log4j2为例
- 通常,代码里都会通过 LoggerFactory.getLogger 来获取 Logger,该 Logger 来自于 slf4j-api 的类
- slf4j-api这个jar包中,除了 LoggerFactory 这个类实现了动态初始化绑定的逻辑,剩下基本都是接口,用于给适配器实现
2.1 slf4j-api的初始化动态绑定过程
该初始化逻辑全部在 org.slf4j.LoggerFactory 中,入口为 performInitialization() ——> bind(),bind()方法中有三个主要逻辑
- findPossibleStaticLoggerBinderPathSet():找到类加载器下 StaticLoggerBinder 的所有子类
- reportMultipleBindingAmbiguity:如果找到多个实现类,打个日志
- StaticLoggerBinder.getSingleton():随机选取一个StaticLoggerBinder.class来创建一个单例
- findPossibleStaticLoggerBinderPathSet():
- 获取LoggerFactory的类加载器:AppClassLoader
- 在该类加载器下,寻找 "org/slf4j/impl/StaticLoggerBinder.class" 的实现类,即适配器类,见下图1
- 见下图2,可以看到项目里找到了两个 StaticLoggerBinder 的实现类,一个是log4j1的,一个是log4j2的
- reportMultipleBindingAmbiguity()
- 如果找到多个匹配的,打日志
- StaticLoggerBinder.getSingleton()
- 随机选取一个
- reportActualBinding(staticLoggerBinderPathSet)
- 打印出真实绑定的