今天无意中发现线上tomcat的catalina.out文件输出大量的zookeeper debug信息,以下是日志片段:
< logger name = “org.apache.zookeeper.ClientCnxn” additivity = “false” >< level value = “INFO” />< appender-ref ref = “console_appender” />logger >
public class ClientCnxn {
private static final Logger LOG = LoggerFactory.getLogger(ClientCnxn. class );
通过上面的图,可以简单的理清关系!commons-logging和slf4j都是日志的接口,供用户使用,而没有提供实现!log4j,logback等等才是日志的真正实现。当我们调用接口时,接口的工厂会自动寻找恰当的实现,返回一个实现的实例给我服务。这些过程都是透明化的,用户不需要进行任何操作。那么,在这个应用里,slf4j到底用的是哪种实现呢?log4j配置貌似没有生效。于是我就顺着源码看了下去。
public static Logger getLogger(String name) {
ILoggerFactory iLoggerFactory = getILoggerFactory();return iLoggerFactory.getLogger(name);}
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=106return TEMP_FACTORY ;}throw new IllegalStateException( “Unreachable code” );}
if ( INITIALIZATION_STATE == UNINITIALIZED ) {INITIALIZATION_STATE = ONGOING_INITIALIZATION ;performInitialization();}
private final static void performInitialization () {bind ();if ( INITIALIZATION_STATE == SUCCESSFUL_INITIALIZATION ) {versionSanityCheck();}}
private final static void bind () {try {Set staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);// the next line does the bindingStaticLoggerBinder.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);}}
private static String STATIC_LOGGER_BINDER_PATH = “org/slf4j/impl/StaticLoggerBinder.class” ;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 iterationSet 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 );}while (paths.hasMoreElements()) {URL path = (URL) paths.nextElement();staticLoggerBinderPathSet.add(path);}} catch (IOException ioe) {Util.report( “Error getting resources from path” , ioe);}return staticLoggerBinderPathSet;}
private static void reportMultipleBindingAmbiguity (Set staticLoggerBinderPathSet) {if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) {Util.report( “Class path contains multiple SLF4J bindings.” );Iterator iterator = staticLoggerBinderPathSet.iterator();while (iterator.hasNext()) {URL path = (URL) iterator.next();Util.report( “Found binding in [“ + path + “]” );}Util.report( “See “ + MULTIPLE_BINDINGS_URL + ” for an explanation.” );}}