An open API service indexing awesome lists of open source software.

https://github.com/watertreestar/tidy-log

light weight logger for Java
https://github.com/watertreestar/tidy-log

java logger logging slf4j-api

Last synced: 3 months ago
JSON representation

light weight logger for Java

Awesome Lists containing this project

README

        

# klog

a simple implementation of slf4j api

slf4j可以选择不同的日志实现,SLF4J隐藏了具体的转换、适配细节,将应用和具体日志框架解耦开来,如果在类路径中没有发现绑定的日志实现,SLF4J默认使用NOP实现。

所以,slf4j只是一套标准的日志API,需要自己去实现,在选择某一个具体的日志实现框架时,只需要将这个框架添加到classpath中,slf4j可以自动实现绑定,这到底是如何实现的呢

## 自动绑定实现类的原理
可以先看看slf4j获取Logger的源码,跟着源码找到其实现自动绑定的原理

从LoggerFactory#getLogger(String name)出发:

```java
public static Logger getLogger(String name) {
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}
// .....
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:
// 调用StaticLoggerBinder获取LoggerFacetoy
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");
}

// performInitialization() 方法
private final static void performInitialization() {
bind();
if (INITIALIZATION_STATE == SUCCESSFUL_INITIALIZATION) {
versionSanityCheck();
}
}

// bind()方法,关键点
private final static void bind() {
try {
Set staticLoggerBinderPathSet = null;
// skip check under android, see also
// http://jira.qos.ch/browse/SLF4J-328
if (!isAndroid()) {
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)) {
// 从这里可以看出需要有一个org.slf.impl.StaticLoggerBinder类
INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
Util.report("Defaulting to no-operation (NOP) logger implementation");
Util.report("See " + NO_STATICLOGGERBINDER_URL + " for further details.");
} else {
failedBinding(ncde);
throw ncde;
}
} catch (java.lang.NoSuchMethodError nsme) {
String msg = nsme.getMessage();
// 从这里我们可以看出需要包含一个getSingleton()方法
if (msg != null && msg.contains("org.slf4j.impl.StaticLoggerBinder.getSingleton()")) {
INITIALIZATION_STATE = FAILED_INITIALIZATION;
Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
Util.report("Your binding is version 1.5.5 or earlier.");
Util.report("Upgrade your binding to version 1.6.x.");
}
throw nsme;
} catch (Exception e) {
failedBinding(e);
throw new IllegalStateException("Unexpected initialization failure", e);
}
}


```

## 一个简单的实现

> 参考自slf4j-simple的实现