剛加入新公司,對日誌的要求比較嚴格,對此特地花了幾天時間看了一下log4j的源碼,大概瞭解了一下log4j的實現方式,總結以下:html
log4j的實現分爲兩個步驟:log4j.xml的加載,logger的使用java
這裏主要有兩個問題,第一個問題是log4j.xml裏的配置信息是怎樣被logger使用的;第二個問題是logger的寫文件是怎樣控制的。apache
第一個問題app
定義一個logger會這樣使用ide
Logger logger = LogManager.getLogger("test");
依次進入getLoggerdebug
/** Retrieve the appropriate {@link Logger} instance. */ public static Logger getLogger(final String name) { // Delegate the actual manufacturing of the logger to the logger repository. return getLoggerRepository().getLogger(name); }
這裏有兩個方法,getLoggerReposityory()和getLogger(),先進入getLoggerRepository 日誌
static public LoggerRepository getLoggerRepository() { if (repositorySelector == null) { repositorySelector = new DefaultRepositorySelector(new NOPLoggerRepository()); guard = null; Exception ex = new IllegalStateException("Class invariant violation"); String msg = "log4j called after unloading, see http://logging.apache.org/log4j/1.2/faq.html#unload."; if (isLikelySafeScenario(ex)) { LogLog.debug(msg, ex); } else { LogLog.error(msg, ex); } } return repositorySelector.getLoggerRepository(); } 這裏repositorySelector是關鍵,最後返回LoggerRepository,repositorySelector是什麼呢?是LogManager類下定義的一個靜態變量 static private RepositorySelector repositorySelector; static { // By default we use a DefaultRepositorySelector which always returns 'h'. Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG)); repositorySelector = new DefaultRepositorySelector(h); /** Search for the properties file log4j.properties in the CLASSPATH. */ String override =OptionConverter.getSystemProperty(DEFAULT_INIT_OVERRIDE_KEY, null); ...
加載配置文件的源代碼以下code
/** A static version of {@link #doConfigure(String, LoggerRepository)}. */ static public void configure(String filename) throws FactoryConfigurationError { new DOMConfigurator().doConfigure(filename, LogManager.getLoggerRepository()); }
是經過LogManager.getLoggerRepository()來加載的,由此解釋第一個問題。xml
第二個問題,logger的寫文件是怎樣控制的htm
這個源代碼有點多,簡單解釋一下,是經過解析log4j.xml或者log4j.property文件,經過反射的方式生成一個一個appender,而後加入到logger維護的一個列表下,當調用info,dubug,error,warn時經過調過遍歷appender來實現對輸入文件的控制
注:看得源碼是針對log4j的1.0版本,估計2.0的版本也差很少
大體看懂了原理,自我標註一下,便於提升