Log4j 2.x使用注意事項

1、主要組件


a) Logger Hierarchy

log4j 1.x中,各個Logger的層級關係都是通過多個Logger來維護的。在log4j 2.x中這種關係將不復存在,取而代之的LoggerConfig對象之間的關係。Logger和LoggerConfig都是一些被命名了的實體,Logger的名稱是大小寫區分的,同時遵從如下命名規則:

如果一個LoggerConfig的名稱加上一個點,是另一個LoggerConfig的名稱前綴,那麼就說這個LoggerConfig是另一個LoggerConfig的祖先;如果一個LoggerConfig與另一個LoggerConfig之間不存在其它祖先LoggerConfig,那麼就說這個LoggerConfig是另一個LoggerConfig的父級。

舉例來說,名稱爲com.foo的LoggerConfig就是名稱爲com.foo.Bar的LoggerConfig的父級。類似的,java是java.util的父級,是java.util.Vector的祖先。這種命名模式對大部分開發者來說是相當熟悉的。

但是有一個例外,那就是Root LoggerConfig,在存在於任何一個LoggerConfig層級的頂端。如下代碼可以將一個LoggerConfig設置爲Root LoggerConfig:
Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

// 或者
Logger logger = LogManager.getRootLogger();

所有的日誌器都可以用LogManager.getLogger靜態方法通過傳遞的Logger名稱來獲取。

b) LoggerContext

在日誌系統中,LoggerContext扮演者重要的角色。然而,根據實際情況,一個應用中可能存在多個有效的LoggerContext。

c) Configuaration

每一個LoggerContext都有一個有效的Configuaration,它包含了Appenders、context-wide Filters、LoggerConfigs以及對StrSubstitutor的引用。在重新配置期間,兩個Configuaration會同時存在;一旦日誌器被重新賦予新的Configuaration,舊的Configuaration就會停止工作並丟棄。具體參見第3部分:配置文件

d) Logger

如前所述,日誌器(Logger)通過調用LogManager.getLogger靜態方法創建。日誌器只是簡單的有一個名詞,並且與一個LoggerConfig關聯。以相同的名稱調用LogManager.getLogger方法將得到同一個日誌器的引用。例如:
Logger x = LogManager.getLogger("wombat");
Logger y = LogManager.getLogger("wombat");
System.out.println(x == y); // 打印true

e) LoggerConfig

f) Filter

g) Appender

h) Layout

i) StrSubstitutor 、StrLookUp

2、jar包引入

package guwen;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class LogTest {
    
    private static final Logger log = LogManager.getLogger(LogTest.class);
    
    public static void main(String[] args) {
        log.error("Hello, Log4j.");
        log.info("Hello, Log4j.");}}
log.debug("Hello, Log4j.") } }

log4j 2.x需要引入兩個jar包,分別是log4j-api.jar和log4j-core.jar。執行上面的代碼,結果如下:

ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

15:11:52.731 [main] ERROR guwen.LogTest - Hello, Log4j.

如果沒有引入log4j-core.jar,也可以運行,但結果如下:

ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...

ERROR LogTest Hello, Log4j.

3、配置文件

從上面的提示可以看出,只需要引入jar包,即使沒有任何配置文件,log4j也能正常工作。但紅色部分提示:在沒有提供配置的情況下,只會打印錯誤信息到控制檯。

log4j 2.x能夠在初始化的時候自動加載配置文件,Log4j2提供了三種ConfiguarationFactory的實現:JSON、YAML、XML。

log4j 2.x的初始化過程爲:

(1)log4j會檢查log4j.configuarationFile系統屬性,如果設置了這個屬性,它就會試着去使用與文件擴展對應的ConfiguarationFactory去加載配置。

(2)如果沒有log4j.configuarationFile系統屬性,YAML ConfiguarationFactory就會試着在classpath中查找log4j2-test.yaml或者log4j2-test.yml;

(3)如果沒有找到yaml配置文件,JSON ConfiguarationFactory就會試着在classpath中查找log4j2-test.json或者log4j2-test.jsn;

(4)如果沒有找到json配置文件,XML ConfiguarationFactory就會試着在classpath中查找log4j2-test.xml;

(5)如果以上測試環境配置文件都無法找到,YAML ConfiguarationFactory就會試着在classpath中查找log4j2.yaml或者log4j2.yml;

(6)如果沒有找到yaml配置文件,JSON ConfiguarationFactory就會試着在classpath中查找log4j2.json或者log4j2.jsn;

(7)如果沒有找到json配置文件,XML ConfiguarationFactory就會試着在classpath中查找log4j2.xml;

(8)如果沒有找到任何配置文件,log4j將會使用DefaultConfiguaration,這會導致日誌被輸出到控制檯。

經過測試,所謂的log4j.configuarationFile屬性,以鍵值對的方式保存在classpath下的log4j2.component.properties屬性文件中,它的取值是指定的配置文件名。

4、日誌級別

在第2部分就已經看到,不提供任何配置時,log4j也能以默認的配置輸出正常日誌信息。以xml配置爲例,實際上默認的配置等價於以下配置文件的配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

將這個文件以log4j2.xml命名,並放置於src目錄下,再次執行上面的代碼,得到如下結果:

19:53:14.646 [main] ERROR guwen.LogTest - Hello, Log4j.

可以看出,打印結果並沒有太大的變化,只是沒有了找不到配置文件的提示信息。但是因爲默認配置中日誌級別是ERROR,所以還是隻打印了Logger.error的執行結果。修改配置中的Root節點的level屬性爲info,再次執行代碼,得到結果如下:

19:56:33.904 [main] ERROR guwen.LogTest - Hello, Log4j.
19:56:33.905 [main] INFO  guwen.LogTest - Hello, Log4j.

再次修改level屬性爲debug,執行代碼,得到結果如下:

19:57:38.704 [main] ERROR guwen.LogTest - Hello, Log4j.
19:57:38.705 [main] DEBUG guwen.LogTest - Hello, Log4j.
19:57:38.705 [main] INFO  guwen.LogTest - Hello, Log4j.

實際上log4j包含7個日誌級別:

  1. 關閉:OFF(0)
  2. 致命:FATAL(100),對應Logger.fatal方法
  3. 錯誤:ERROR(200),對應Logger.error方法
  4. 警告:WARN(300),對應Logger.warn方法
  5. 信息:INFO(400),對應Logger.info方法
  6. 調試:DEBUG(500),對應Logger.debug方法
  7. 跟蹤:TRACE(600),對應Logger.trace方法
  8. 全部:ALL(Integer.MAX_VALUE)
當指定某一個級別時,比如DEBUG,那麼所有低於這個級別的其它級別日誌,都會被打印。當指定級別爲DEBUG時,Logger.debug、Logger.info、Logger.warn、Logger.error以及Logger.fatal等方法都能輸出日誌,但Logger.trace無法輸出日誌。




發佈了40 篇原創文章 · 獲贊 6 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章