log4j2 使用說明


因近期需要編寫J2EE程序,所以簡單學習了Log4j2,這里把我學習的一些信息做記錄:

 

1、從HelloWorld開始

參考:http://logging.apache.org/log4j/2.x/manual/api.html

首先創建一個Java Project,如下圖,在項目中創建lib文件夾,將log4japicore包復制進去並配置到項目編譯路徑中。

創建包com.demo並在包內創建類HelloWorld

 

HelloWorld類的內容如下:

package com.demo;

 

import org.apache.logging.log4j.LogManager;

import org.apache.logging.log4j.Logger;

 

public class HelloWorld {

    private static final Logger logger = LogManager.getLogger("HelloWorld");

    public static void main(String[] args) {    

     String hello = "Hello, World!";    

        logger.trace("TRACE: " + hello);

        logger.debug("DEBUG: " + hello);

        logger.info("INFO: " + hello);

        logger.warn("WARN: " + hello);

        logger.error("ERROR: " + hello);

        logger.fatal("FATAL: " + hello);

    }

}

運行HelloWorld,結果顯示如下:

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

00:06:16.530 [main] ERROR HelloWorld - ERROR: Hello, World!

00:06:16.532 [main] FATAL HelloWorld - FATAL: Hello, World!

 

運行時提示沒有找到Log4j2的配置文件,使用默認配置,只顯示error到控制台。

缺省的配置等同於如下配置,其中Root指定的level是error,所有只輸出了error和fatal級別的日志。

<?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>

 

2、理解log4j2的結構

參考:http://logging.apache.org/log4j/2.x/manual/architecture.html

結合我們的HelloWorld程序,我們看一下log4j2的結構:

LoggerContext是整個Log系統的錨點,每一個LoggerContext會含有一個Configuration,在congfiguration中會包含Appender(輸出器)、Filter(過濾器)、LoggerConfigStrSubstitutor的引用。

當我們在配置文件中聲明一個Loggers時就會創建一個LoggerConfig, LoggerConfig包含有一組Filter,同時持有一組Appender的引用。LoggerConfig所收到的所有LogEvent首先經過過濾器處理才會傳遞給Appendar輸出。

Filter會存在三種返回結果:AcceptDenyNeutralAccept表示事件將直接被處理並不繼續轉發其他FilterDeny表示事件將被忽略,Neutral表示事件將被轉發給下一個filter,如果沒有后續的filter,事件將被處理。

 

3、理解Named Hierarchy (日志名稱層次規則)

首先我們在com.demo包內新增一個類NamedHierarchy:

package com.demo;

 

import org.apache.logging.log4j.LogManager;

import org.apache.logging.log4j.Logger;

 

public class NamedHierarchy {

 private static final Logger logger = LogManager.getLogger(NamedHierarchy.class);

public static void main(String[] args) {

// TODO Auto-generated method stub

String nh = "Named Hierarchy";    

logger.getLevel();

        logger.trace("TRACE: " + nh + " " + logger.getLevel());       

        NamedHierarchy n = new NamedHierarchy();

        n.run();

        logger.error("ERROR: " + nh + " " + logger.getLevel());

        

}

 

public void run(){

String nh = "NamedHierarchy.run";    

     logger.debug("DEBUG: " + nh + " " + logger.getLevel());     

}

}

 

src下新增log4j2.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>

     <Logger name="com.demo.NamedHierarchy" level="trace">

       <AppenderRef ref="Console"/>

</Logger>

<Logger name="com.demo" level="debug">

       <AppenderRef ref="Console"/>

</Logger>

    <Root level="error">

      <AppenderRef ref="Console"/>

    </Root>    

  </Loggers>

</Configuration>

 

工程結構如下:

 

運行NamedHierarchy你會發現結果如下:

01:33:48.864 [main] TRACE com.demo.NamedHierarchy - TRACE: Named Hierarchy TRACE

01:33:48.864 [main] TRACE com.demo.NamedHierarchy - TRACE: Named Hierarchy TRACE

01:33:48.864 [main] TRACE com.demo.NamedHierarchy - TRACE: Named Hierarchy TRACE

01:33:48.867 [main] DEBUG com.demo.NamedHierarchy - DEBUG: NamedHierarchy.run TRACE

01:33:48.867 [main] DEBUG com.demo.NamedHierarchy - DEBUG: NamedHierarchy.run TRACE

01:33:48.867 [main] DEBUG com.demo.NamedHierarchy - DEBUG: NamedHierarchy.run TRACE

01:33:48.868 [main] ERROR com.demo.NamedHierarchy - ERROR: Named Hierarchy TRACE

01:33:48.868 [main] ERROR com.demo.NamedHierarchy - ERROR: Named Hierarchy TRACE

01:33:48.868 [main] ERROR com.demo.NamedHierarchy - ERROR: Named Hierarchy TRACE

為什么同樣的日志信息會被輸出三次呢?這是因為logger的命名符合命名層次規則,而層次關系是由對應的LoggerConfig來維護的。root是整個層次規則(或結構)的頂層,父節點和子節點是通過“.”來識別的,如com.demo是com.demo.NamedHierarchy的父節點,com.demo.NamedHierarchy是com.demo的子節點。

同時Logger的命名和類的命名又有關聯的,如果我們在配置文件中配置一個Logger的名稱為com.demo.NamedHierarchy,那么類com.demo.NamedHierarchy中的Logger就會匹配到這一配置,同時所有父節點的配置也會被適用。所以在我們使用logger.trace("TRACE: " + nh + " " + logger.getLevel()); 輸出日志時,配置文件中3Logger對應的Appender分別被調用。

如果你把

<Logger name="com.demo.NamedHierarchy" level="trace">

修改為

<Logger name="com.demo.NamedHierarchy" level="error">

運行,結果如下:

21:40:44.389 [main] ERROR com.demo.NamedHierarchy - ERROR: Named Hierarchy ERROR

21:40:44.389 [main] ERROR com.demo.NamedHierarchy - ERROR: Named Hierarchy ERROR

21:40:44.389 [main] ERROR com.demo.NamedHierarchy - ERROR: Named Hierarchy ERROR

為什么父節點的Appender沒有輸出?這是由於LogEventlevelLoggerConfiglevel在特定組合下,LogEvent不會被繼續向下轉發處理,組合關系如下,其中YES表示轉發繼續處理,NO表示不繼續轉發。

 

Event Level

LoggerConfig Level

TRACE

DEBUG

INFO

WARN

ERROR

FATAL

OFF

ALL

YES

YES

YES

YES

YES

YES

NO

TRACE

YES

NO

NO

NO

NO

NO

NO

DEBUG

YES

YES

NO

NO

NO

NO

NO

INFO

YES

YES

YES

NO

NO

NO

NO

WARN

YES

YES

YES

YES

NO

NO

NO

ERROR

YES

YES

YES

YES

YES

NO

NO

FATAL

YES

YES

YES

YES

YES

YES

NO

OFF

NO

NO

NO

NO

NO

NO

NO

 

如果你不希望LogEvent被按命名層次分別處理,只希望最低一層的子節點處理,那么可以在Logger配置時增加additivity="false",如:

<Logger name="com.demo.NamedHierarchy" level="trace" additivity="false">

       <AppenderRef ref="Console"/>

</Logger>

 

4、定時重新加載配置

Log4j2支持定時檢查配置文件是否變化並根據變化重新加載,這個功能在實際應用中比較有價值,比如產品上網后有問題,如果默認的error級別的日志不能支撐定位,需要切換到trace級別,定時加載的功能就可以避免重啟服務,畢竟商用產品重啟服務代價還是很大的,有時候還必須先獲取客戶的授權。

Configuration中增加monitorInterval="30"參數,其中3030秒,如下:

<Configuration monitorInterval="30">

...

</Configuration>

 

5、常用的Appender

關於詳細的Appender及配置參數,建議查看APIhttp://logging.apache.org/log4j/2.x/manual/appenders.html

5.1 FileAppender

FileAppender支持把日志信息寫入文件,典型的配置如下:

append用來設置程序開始時日志是否被追加到原日志文件上,fileName表示要保存的文件名稱,bufferedIObufferSize表示將日志內容緩存到bufferSize大小后寫入文件:

<?xml version="1.0" encoding="UTF-8"?>

<Configuration>

  <Appenders>

    <File name="MyFile" append="true" fileName="logs/mylog.log" bufferedIO="true" bufferSize="512">

      <PatternLayout>

        <Pattern>%d{MM-dd-yyyy} %p %c{1.} [%t] %m%n</Pattern>

      </PatternLayout>

    </File>

  </Appenders>

  <Loggers>

    <Root level="error">

      <AppenderRef ref="MyFile"/>

    </Root>

  </Loggers>

</Configuration>

5.2 RollingFileAppender

循環寫入文件,典型配置如下:

以下的配置可以簡單概括為:初始日志名稱是rolling.log,當rolling.log日志文件達到1KB時,將rolling.log修改為app-日期-1.log並壓縮為app-日期-1.log.gzrolling.log重新開始寫;當再次達到1KB時,將rolling.log修改為app-日期-2.log並壓縮為app-日期-2.log.gzrolling.log重新開始寫;當再次達到1KB時,刪除app-日期-1.log.gz,修改app-日期-2.log.gzapp-日期-1.log.gz,將rolling.log修改為app-日期-2.log並壓縮為app-日期-2.log.gzrolling.log重新開始寫;

<?xml version="1.0" encoding="UTF-8"?>

<Configuration>

  <Appenders>

    <RollingFile name="RollingFile" fileName="logs/rolling.log"

                 filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">

      <PatternLayout>

        <Pattern>%d{MM-dd-yyyy} %p %c{1.} [%t] %m%n</Pattern>

      </PatternLayout>

      <Policies>

        <TimeBasedTriggeringPolicy />

        <SizeBasedTriggeringPolicy size="1 KB"/>

      </Policies>

      <DefaultRolloverStrategy fileIndex="max" max="2"/>

    </RollingFile>

  </Appenders>

  <Loggers>

    <Root level="error">

      <AppenderRef ref="RollingFile"/>

    </Root>

  </Loggers>

</Configuration>

建議你使用此配置寫一個簡單的腳步驗證效果。

更多詳細內容,請查看官方文檔:http://logging.apache.org/log4j/2.x/manual/architecture.html

http://blog.csdn.net/axwolfer/article/details/40718609

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM