簡析log4j的實現方式

剛加入新公司,對日誌的要求比較嚴格,對此特地花了幾天時間看了一下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的版本也差很少

大體看懂了原理,自我標註一下,便於提升

相關文章
相關標籤/搜索