日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

从源码角度深入分析log4j配置文件使用

發(fā)布時間:2025/4/5 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从源码角度深入分析log4j配置文件使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

log4j在日常開發(fā)中經(jīng)常使用,但有時候?qū)?配置文件應(yīng)該放到什么位置有疑惑。現(xiàn)在我們通過從代碼的角度來看待這個問題,

看完后你也許會恍然大悟哦。

開始吧。

Log4j的組成及架構(gòu):

? Log4j由三個重要的組成構(gòu)成:日志記錄器(Loggers),輸出端(Appenders)和日志格式化器(Layout)。

1.日志記錄器(Loggers):控制要輸出哪些日志記錄語句,對日志信息進行級別限制。
2.輸出端(Appenders):指定了日志將打印到控制臺還是文件中。

3.日志格式化器(Layout):控制日志信息的顯示格式。

類圖結(jié)構(gòu)如下(不要眼花繚亂,我辛辛苦苦一個一個畫出來的):

?

log4j初始化

從架構(gòu)上我們可以看出logger的實現(xiàn)是從logManager來具體完成的,因此初始化在logManager的static塊中,如下:

static {// By default we use a DefaultRepositorySelector which always returns 'h'.Hierarchy h = new Hierarchy(new RootLogger(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);// if there is no default init override, then get the resource// specified by the user or the default config file.if(override == null || "false".equalsIgnoreCase(override)) {String configurationOptionStr = OptionConverter.getSystemProperty(DEFAULT_CONFIGURATION_KEY, null);String configuratorClassName = OptionConverter.getSystemProperty(CONFIGURATOR_CLASS_KEY, null);URL url = null;// if the user has not specified the log4j.configuration// property, we search first for the file "log4j.xml" and then// "log4j.properties"if(configurationOptionStr == null) { url = Loader.getResource(DEFAULT_XML_CONFIGURATION_FILE);if(url == null) {url = Loader.getResource(DEFAULT_CONFIGURATION_FILE);}} else {try {url = new URL(configurationOptionStr);} catch (MalformedURLException ex) {// so, resource is not a URL:// attempt to get the resource from the class pathurl = Loader.getResource(configurationOptionStr); } }// If we have a non-null url, then delegate the rest of the// configuration to the OptionConverter.selectAndConfigure// method.if(url != null) {LogLog.debug("Using URL ["+url+"] for automatic log4j configuration.");try {OptionConverter.selectAndConfigure(url, configuratorClassName,LogManager.getLoggerRepository());} catch (NoClassDefFoundError e) {LogLog.warn("Error during default initialization", e);}} else {LogLog.debug("Could not find resource: ["+configurationOptionStr+"].");}} else {LogLog.debug("Default initialization of overridden by " + DEFAULT_INIT_OVERRIDE_KEY + "property."); } }

讓我們深入進去看看是怎么初始化的?

第一步:創(chuàng)建一個默認的RepositorySelector,RepositorySelector在logManager中使用,它的實現(xiàn)類對特定的應(yīng)用上下文提供了一個LoggerRespository。LoggerRespository的實現(xiàn)類負責追蹤應(yīng)用上下文。ResponsitorySelector提供了一個方法:

public?LoggerRepository getLoggerRepository();

LoggerRepository從字面上理解,它是一個Logger的容器,它會創(chuàng)建并緩存Logger實例,從而具有相同名字的Logger實例不會多次創(chuàng)建,以提高性能。它的這種特性有點類似Spring的IOC概念。Log4J支持兩種配置文件:properties文件和xml文件。Configurator解析配置文件,并將解析后的信息添加到LoggerRepository中。LogManager最終將LoggerRepository和Configurator整合在一起。

LoggerRepository是一個Logger的容器,它負責創(chuàng)建、緩存Logger實例,同時它也維護了Logger之間的關(guān)系,因為在Log4J中,所有Logger都組裝成以RootLogger為根的一棵樹,樹的層次由Logger的Name來決定,其中以’.’分隔。

除了做為一個Logger容器,它還有一個Threshold屬性,用于過濾所有在Threshold級別以下的日志。以及其他和Logger操作相關(guān)的方法和屬性。

public interface LoggerRepository { public void addHierarchyEventListener(HierarchyEventListener listener);boolean isDisabled(int level);public void setThreshold(Level level);public void setThreshold(String val); public void emitNoAppenderWarning(Category cat);public Level getThreshold();public Logger getLogger(String name); public Logger getLogger(String name, LoggerFactory factory);public Logger getRootLogger(); public abstract Logger exists(String name); public abstract void shutdown(); public Enumeration getCurrentLoggers();public abstract void fireAddAppenderEvent(Category logger, Appender appender);public abstract void resetConfiguration(); }

Hierarchy類

Hierarchy是Log4J中默認對LoggerRepository的實現(xiàn)類,它用于表達其內(nèi)部的Logger是以層次結(jié)構(gòu)存儲的。在對LoggerRepository接口的實現(xiàn)中,getLogger()方法是其最核心的實現(xiàn),因而首先從這個方法開始。Hierarchy中用一個Hashtable來存儲所有Logger實例,它以CategoryKey作為key,Logger作為value,其中CategoryKey是對Logger中Name字符串的封裝,之所以要引入這個類是出于性能考慮,因為它會緩存Name字符串的hash code,這樣在查找過程中計算hash code時就可以直接取得而不用每次都計算。

第二步:從classpath路徑查找log4j.properties屬性配置文件。

? ?1. 判斷配置文件有沒有重寫?

/** Search for the properties file log4j.properties in the CLASSPATH. */String override =OptionConverter.getSystemProperty(DEFAULT_INIT_OVERRIDE_KEY,null); //public static final String DEFAULT_INIT_OVERRIDE_KEY = "log4j.defaultInitOverride"; publicstatic String getSystemProperty(String key, String def) {try {return System.getProperty(key, def);} catch(Throwable e) { // MS-Java throws com.ms.security.SecurityExceptionExLogLog.debug("Was not allowed to read system property \""+key+"\".");return def;}}

? ?2. override為null或者為false時沒有重寫,然后從系統(tǒng)屬性中查找key:log4j.configuration和log4j.configuratorClass屬性。如果沒有設(shè)置log4j.configuration屬性,就查找log4j.xml,然后查找log4j.properties文件。使用方法:

if(configurationOptionStr == null) { url = Loader.getResource(DEFAULT_XML_CONFIGURATION_FILE);if(url == null) {url = Loader.getResource(DEFAULT_CONFIGURATION_FILE);}

使用java2的線程上下文類加載器來查找資源,如果查找失敗,則使用加載該類(loader)的類加載器來加載資源。

3.如果設(shè)置了log4j.configuration屬性,則使用url形式讀取,如果資源不是url,則從classpath獲取資源:

try {url = new URL(configurationOptionStr);} catch (MalformedURLException ex) {// so, resource is not a URL:// attempt to get the resource from the class pathurl = Loader.getResource(configurationOptionStr); }

4. 如果log4j.configuration屬性為url形式:

// If we have a non-null url, then delegate the rest of the// configuration to the OptionConverter.selectAndConfigure// method.if(url != null) {LogLog.debug("Using URL ["+url+"] for automatic log4j configuration.");try {OptionConverter.selectAndConfigure(url, configuratorClassName,LogManager.getLoggerRepository());} catch (NoClassDefFoundError e) {LogLog.warn("Error during default initialization", e);}} else {LogLog.debug("Could not find resource: ["+configurationOptionStr+"].");}

小結(jié):

The exact default initialization algorithm is defined as follows:

  • Setting the?log4j.defaultInitOverride?system property to any other value then "false" will cause log4j to skip the default initialization procedure (this procedure).
  • Set the?resource?string variable to the value of the?log4j.configuration?system property.?The preferred way to specify the default initialization file is through the?log4j.configuration?system property.?In case the system property?log4j.configuration?is not defined, then set the string variable?resourceto its default value "log4j.properties".
  • Attempt to convert the?resource?variable to a URL.
  • If the resource variable cannot be converted to a URL, for example due to a?MalformedURLException, then search for the?resource?from the classpath by calling?org.apache.log4j.helpers.Loader.getResource(resource, Logger.class)?which returns a URL. Note that the string "log4j.properties" constitutes a malformed URL.

    See?Loader.getResource(java.lang.String)?for the list of searched locations.

  • If no URL could not be found, abort default initialization. Otherwise, configure log4j from the URL.

    The?PropertyConfigurator?will be used to parse the URL to configure log4j unless the URL ends with the ".xml" extension, in which case the?DOMConfiguratorwill be used. You can optionaly specify a custom configurator. The value of the?log4j.configuratorClass?system property is taken as the fully qualified class name of your custom configurator. The custom configurator you specify?must?implement the?Configurator?interface.

  • ?

    ?

    參考文獻:

    1.?http://www.2cto.com/kf/201207/139798.html

    2.?http://logging.apache.org/log4j/1.2/manual.html

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/4243161.html

    總結(jié)

    以上是生活随笔為你收集整理的从源码角度深入分析log4j配置文件使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。