刚加入新公司,对日志的要求比较严格,对此特地花了几天时间看了一下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的版本也差很少
大体看懂了原理,自我标注一下,便于提升