Skip to main content

log4j打印日志的原理

· 2 min read
jeesk

log4j-slf4j-impl: log4j的日志转到slf4j上

LoggerFactory.getLogger () 方法 寻找对应的logger

org.slf4j.LoggerFactory#findPossibleStaticLoggerBinderPathSet 寻找staticLoggerBinder

paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH); 通过路径寻找所有的binder, 这里的STATIC_LOGGER_BINDER_PATH = org/slf4j/impl/StaticLoggerBinder.class, 每个slf4j的具体实现类都有一个StaticLoggerBinder.class

org.slf4j.LoggerFactory#reportMultipleBindingAmbiguity 判断是否有多个binder, 如果有将会打印日志: SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/Z:/repository/org/slf4j/slf4j-simple/1.7.28/slf4j-simple-1.7.28.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/Z:/repository/org/slf4j/slf4j-nop/1.7.28/slf4j-nop-1.7.28.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.., 这个日志是我们常见的, 因为有多个日志实现

org/slf4j/impl/StaticLoggerBinder.class, 每个slf4j的日志实现都有这个类 找到所有绑定的logger

调用 StaticLoggerBinder.getSingleton(); 这里如果有多个class, 应该是按顺序调用第一个class的getSingleton(), 调用 reportActualBinding 打印绑定的是哪一个日志实现 SLF4J: Actual binding is of type [org.slf4j.impl.SimpleLoggerFactory] getILoggerFactory() 获得到刚才StaticLoggerBinder的日志工厂 SimpleLoggerFactory.getLogger public Logger getLogger(String name) { Logger simpleLogger = (Logger)this.loggerMap.get(name); if (simpleLogger != null) { return simpleLogger; } else { Logger newInstance = new SimpleLogger(name); Logger oldInstance = (Logger)this.loggerMap.putIfAbsent(name, newInstance); return (Logger)(oldInstance == null ? newInstance : oldInstance); } } 指定的logger 作缓存, 然后调用info() 方法打印日志.