LogFacade---SLF4J
概述
Simple Logging Facade for Java(SLF4J);
用作各种日志框架(eg:java.util.logging,logback,log4j)的简单外观或抽象,允许最终用户在部署 时插入所需的日志记录框架;
不提供完整的日志记录解决方案;
使用SLF4J无法执行配置appender或设置日志记录级别等操作。
因此,在某个时间点,任何非平凡的应用程序都需要直接调用底层日志记录系统;
因此一般情况下slf4j都会和log4j,logback等日志框架一起使用;
slf4j是一个日志标准,同时日志框架都会实现这个标准,因此使用slf4j可以极大的降低维护成本;
SPI机制


slf4j 提供的 service LoggerFactory ,在Classpath下查找 org/slf4j/impl/StaticLoggerBinder.class
链路
LoggerFactory.getLogger
// org.slf4j.LoggerFactory.getLogger(java.lang.Class)
// Return a logger named corresponding to the class passed as parameter, using the statically bound {@link ILoggerFactory} instance.
public static Logger getLogger(Class clazz) {
return getLogger(clazz.getName());
}
// org.slf4j.LoggerFactory.getLogger(java.lang.String)
// Return a logger named according to the name parameter using the statically bound {@link ILoggerFactory} instance.
public static Logger getLogger(String name) {
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}
// org.slf4j.LoggerFactory.getILoggerFactory
// Return the {@link ILoggerFactory} instance in use.ILoggerFactory instance is bound with this class at compile time.
public static ILoggerFactory getILoggerFactory() {
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://bugzilla.slf4j.org/show_bug.cgi?id=106
return TEMP_FACTORY;
}
throw new IllegalStateException("Unreachable code");
}
// org.slf4j.LoggerFactory.performInitialization
private final static void performInitialization() {
bind();
if (INITIALIZATION_STATE == SUCCESSFUL_INITIALIZATION) {
versionSanityCheck();
}
}
// org.slf4j.LoggerFactory.bind
private final static void bind() {
try {
Set staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet(); // 获取classpath下的org/slf4j/impl/StaticLoggerBinder.class
reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
// the next line does the binding
StaticLoggerBinder.getSingleton(); //
INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
reportActualBinding(staticLoggerBinderPathSet);
emitSubstituteLoggerWarning();
} catch (NoClassDefFoundError ncde) {
String msg = ncde.getMessage();
if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
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();
if (msg != null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1) {
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);
}
}
// org.slf4j.LoggerFactory.findPossibleStaticLoggerBinderPathSet
// We need to use the name of the StaticLoggerBinder class, but we can't reference the class itself.
private static Set findPossibleStaticLoggerBinderPathSet() {
// use Set instead of list in order to deal with bug #138
// LinkedHashSet appropriate here because it preserves insertion order during iteration
Set staticLoggerBinderPathSet = new LinkedHashSet();
try {
ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
Enumeration paths;
if (loggerFactoryClassLoader == null) {
paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
} else {
paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH); // 获取classpath下的org/slf4j/impl/StaticLoggerBinder.class
}
while (paths.hasMoreElements()) {
URL path = (URL) paths.nextElement();
staticLoggerBinderPathSet.add(path);
}
} catch (IOException ioe) {
Util.report("Error getting resources from path", ioe);
}
return staticLoggerBinderPathSet;
}
// org.slf4j.impl.StaticLoggerBinder.getSingleton
public static StaticLoggerBinder getSingleton() {
return SINGLETON;
}
// ch.qos.logback.classic.LoggerContext.getLogger(java.lang.String)
public final Logger getLogger(final String name) {
//...
Logger childLogger = (Logger) loggerCache.get(name); // 从缓存中取对应name的Logger
//...
loggerCache.put(childName, childLogger);
}
log.debug
由具体的 log 实现;
浙公网安备 33010602011771号