日志框架组合
slf4j+logback
引入依赖
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${
slf4j.version}</version>
<scope>compile</scope>
</dependency>
- slf4j-api提供日志门面抽象,包括
- LoggerFactoryBinder:日志工厂绑定抽象
- ILoggerFactory:日志工厂抽象
- Logger:日志抽象
- logback-classic提供
- StaticLoggerBinder:日志工厂绑定实现
- LogContext:日志工厂实现
- Logger:日志实现
- ContextInitializer:日志工厂初始化
- logback-core提供
- 日志工厂初始化相关配置
slf4j通过如下方式调用,项目中可直接使用,jcl-over-slf4j和spring-jcl中最终也是调用此方法将日志转换到slf4j
private static Logger log = LoggerFactory.getLogger(TestController.class);
- getLogger(String name)
getLogger(String name)是具体执行 的方法,一共分两步:
-
获取日志工厂;
-
从日志工厂获取log对象并返回。
ILoggerFactory是slf4j提供的日志工厂类接口标准,支持slf4j门面的日志框架需要实现此接口
public final class LoggerFactory {
public static Logger getLogger(String name) {
#获取日志工厂
ILoggerFactory iLoggerFactory = getILoggerFactory();
#获取日志类
return iLoggerFactory.getLogger(name);
}
}
获取日志工厂
getILoggerFactory()主要的作用是执行日志工厂绑定,将slf4j门面和具体的日志实现进行绑定
public final class LoggerFactory {
static final int UNINITIALIZED = 0;
static final int ONGOING_INITIALIZATION = 1;
static final int FAILED_INITIALIZATION = 2;
static final int SUCCESSFUL_INITIALIZATION = 3;
static final int NOP_FALLBACK_INITIALIZATION = 4;
static volatile int INITIALIZATION_STATE = UNINITIALIZED;
public static ILoggerFactory getILoggerFactory() {
#如果状态是未初始化,执行初始化
if (INITIALIZATION_STATE == UNINITIALIZED) {
synchronized (LoggerFactory.class) {
if (INITIALIZATION_STATE == UNINITIALIZED) {
#状态变更为正在进行初始化
INITIALIZATION_STATE = ONGOING_INITIALIZATION;
#执行初始化逻辑
performInitialization();
}
}
}
switch (INITIALIZATION_STATE) {
case SUCCESSFUL_INITIALIZATION:
return StaticLoggerBinder.getSingleton().getLoggerFactory();
case NOP_FALLBACK_INITIALIZATION:
return NOP_FALLBACK_FACTORY;
case FAILED_INITIALIZATION:
throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
case ONGOING_INITIALIZATION:
// support re-entrant behavior.
// See also http://jira.qos.ch/browse/SLF4J-97
return SUBST_FACTORY;
}
throw new IllegalStateException("Unreachable code");
}
}
LoggerFactory中定义了5种状态,分别为
- UNINITIALIZED = 0;未初始化
- ONGOING_INITIALIZATION = 1;正在初始化
- FAILED_INITIALIZATION = 2;初始化失败
- SUCCESSFUL_INITIALIZATION = 3;初始化成功
- NOP_FALLBACK_INITIALIZATION = 4;
同时使用INITIALIZATION_STATE记录当前状态,初始状态为INITIALIZATION_STATE=UNINITIALIZED,随着方法执行,状态随之流转。首次调用方法,状态变更INITIALIZATION_STATE=ONGOING_INITIALIZATION,同时执行performInitialization()方法执行初始化
- performInitialization()
performInitialization()主要的作用是执行绑定和版本兼容性检查,检查绑定的日志门面的版本和日志实现的版本是否能够匹配
public final class LoggerFactory {
private final static void performInitialization() {
#绑定具体日志框架实现
bind();
if (INITIALIZATION_STATE == SUCCESSFUL_INITIALIZATION) {
#版本兼容性检查
versionSanityCheck();
}
}
}
- bind()
bind()的核心是StaticLoggerBinder.getSingleton(),用来和日志实现框架进行绑定,实现slf4j门面的日志框架需要提供 org.slf4j.impl.StaticLoggerBinder类 ,如果项目中同时引用了多个StaticLoggerBinder,根据pom文件中的顺序决定使用哪个,最上面的优先使用
public final class LoggerFactory {
private final static void bind() {
try {
Set<URL> staticLoggerBinderPathSet = null;
// skip check under android, see also
// http://jira.qos.ch/browse/SLF4J-328
#判断是否是安卓系统
if (!isAndroid()) {
#找出所有包含org/slf4j/impl/StaticLoggerBinder.class的类
staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
#如果有多个,输出报告都是谁
reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
}
// the next line does the binding
#核心方法,真正执行绑定
StaticLoggerBinder.getSingleton();
#状态变更为初始化成功
INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
#如果有多个,输出报告具体绑定了谁
reportActualBinding(staticLoggerBinderPathSet);
fixSubstituteLoggers();
replayEvents();
// release all resources in SUBST_FACTORY
SUBST_FACTORY.clear();
} catch (NoClassDefFoundError ncde) {
String msg = ncde.getMessage();
if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
Util.report("Failed to load class \"org.s