Java日誌體系(六)log4j2

 

1.1 簡介

            

log4j2,一個日誌的實現框架,是log4j的升級版本,於2014年7月正式亮相。與第一代log4j不一樣,log4j2徹底重寫了log4j的日誌實現,並非在原有基礎上進行的升級,解決了log4j中的一些問題,例如:多線程下性能低下、api不支持佔位符{}的使用、配置文件不能自動從新加載等。apache

爲何說log4j在多線程狀況下性能低下呢?主要是synchronized鎖在做怪,當咱們的log4jzai 獲取appender對象時,須要進行加鎖處理;而接下來對appender操做(將要進行日誌打印)時,也進行了加鎖處理,這樣一來性能天然得不到提高,從而致使整個應用的qps降低。json

而在log4j2中,因爲引入了異步logger,使得log4j2的性能獲得了巨大的提高,相比於log4j,logback而言,提高了數10倍之多。關於異步logger的狀況,咱們後面進行講解。api

 

1.2 log4j2結構

                

 

LoggerContext:Logger上下文,主要負責讀取log4j2的配置以及獲取Logger對象的工做;緩存

Logger:日誌對象,負責日誌信息的打印;跟以前的幾個日誌框架相同,log4j2也包含了5大日誌級別,分別爲TRACE,DEBUG,INFO,WARN,ERROR 以及FATAL;具體等級以下:TRACE < DEBUG < INFO < WARN < ERROR < FATAL;多線程

LoggerConfig:Logger的配置對象,每個Logger的配置信息就是一個LoggerConfig對象;併發

Configuration:log4j2配置文件的解析,當咱們的配置文件是xml的格式時,具體的實現是XmlConfiguration;每個LoggerContext都有一個Configuration對象,包含了全部的Appender、Filter、LoggerConfigapp

 

1.3 使用

首先,須要在應用的pom.xml中添加依賴:框架

<dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>

其次,聲明測試代碼:異步

public class log4j2Demo { private Logger logger = LogManager.getLogger(log4j2Demo.class); @Test public void test() throws InterruptedException { logger.error("Error Message!"); logger.warn("Warn Message!"); logger.info("Info Message!"); logger.debug("Debug Message!"); logger.trace("Trace Message!"); } }

最後,在classpath下聲明配置文件:log4j2.xml:性能

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" monitorInterval="30">
    <Appenders>
        <!--控制檯-->
        <Console name="Console" target="SYSTEM_OUT">-->
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>

        <!--普通文件:-->
        <File name="File" fileName="e:/log.out" append="true" immediateFlush="true" >
            <PatternLayout>
                <Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %L- %msg%n</Pattern>
            </PatternLayout>
        </File>
    </Appenders>
    <Loggers>
        <Root level="debug" >
            <AppenderRef ref="File"/>
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

經過以上步驟,log4j2就能夠正常的運行了。

 

1.4 log4j2配置文件詳解

與log4j不一樣的是,log4j2只支持.xml或者.json格式的配置文件,不在支持.properties格式的配置文件。那麼,下面咱們就以.xml來進行講解:

默認狀況下,系統會在classpath下查找配置文件:(按照如下順序)

1.classpath下名爲 log4j-test.json 或者log4j-test.jsn文件 2.classpath下名爲 log4j2-test.xml 3.classpath下名爲 log4j.json 或者log4j.jsn文件 4.classpath下名爲 log4j2.xml

請注意,此處咱們經常使用的是log4j2.xml,這塊與log4j不一樣;

如下是log4j2經常使用的配置信息:(逐一進行講解)

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" monitorInterval="30">
    <Appenders>

        <!--控制檯-->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>

        <!--普通文件:-->
        <File name="File" fileName="e:/log.out" append="true" immediateFlush="false" bufferedIO="true" bufferSize="1024">
            <PatternLayout>
                <Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %L- %msg%n</Pattern>
            </PatternLayout>
        </File>

        <!--異步appender:-->
        <Async name="Async">
            <AppenderRef ref="File"/>
        </Async>

        <!--循環寫入文件:-->
        <RollingFile name="RollingFile" fileName="e:/log.out" filePattern="e:/app-%d{yyyy-MM-dd_HH-mm}-%i.out">
            <PatternLayout>
                <Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern>
            </PatternLayout>
            <!--滾動策略:-->
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="100 kb"/> 
            </Policies>
            <DefaultRolloverStrategy max="5"/>
        </RollingFile>

    </Appenders>

    <Loggers>
       
        <!--單獨指定logger-->
        <Logger name="com.jiaboyan.logDemo.log4j2Demo" level="info" additivity="false" includeLocation="true">
            <AppenderRef ref="File"/>
        </Logger>
        
        <!--根logger-->
        <Root level="info" >
            <AppenderRef ref="Async"/>
            <AppenderRef ref="File"/>
            <AppenderRef ref="Console"/>
        </Root>
        
        <!--異步logger-->
        <AsyncRoot level="info">
            <AppenderRef ref="File"/>
        </AsyncRoot>
    </Loggers>

</Configuration>

1.Configuration -- 根節點

<Configuration status="debug" monitorInterval="30"></Configuration> Configuration:表示log4j2中的Configuration對象,實際爲XmlConfiguration; status:表示log4j2自己的日誌信息打印級別,當設置爲TRACE 或者 DEBUG 級別時,便會打印出log4j2內部初始化的一些日誌信息; monitorInterval:表示每隔必定時間從新加載log4j2配置文件,單位秒;

2.Appenders -- Console

<Console name="Console" target="SYSTEM_OUT">
    <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console> name:表示控制檯Appender的名稱,<logger>中會依賴此名稱,起名沒有具體要求,但最好簡明直譯; target:表示ConsoleAppender使用哪一種方式將日誌輸出到控制檯,通常調用System.out.println()方法; PatternLayout--pattern:表示日誌信息輸出的格式;

3.Appenders -- File

<File name="File" fileName="e:/log.out" append="true" immediateFlush="false" bufferedIO="true" bufferSize="8096">
    <PatternLayout>
        <Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %L- %msg%n</Pattern>
    </PatternLayout>
</File> name:表示文件Appender的名稱,<logger>中會依賴此名稱,起名沒有具體要求,但最好簡明直譯; fileName:表示生成的日誌文件名稱; append:表示新生成的日誌是否追加到日誌文件中,若是爲true則表示追加,false表示覆蓋原有日誌信息; immediateFlush:表示日誌打印請求是否當即輸出,true爲當即,false表示使用緩存; bufferedIO:表示日誌打印請求是否使用緩存,true爲使用,false爲不使用; bufferSize:表示日誌打印請求的使用緩存的大小,默認爲8096字節; PatternLayout--pattern:同上;

4.Appenders -- RollingFile

<RollingFile name="RollingFile" fileName="e:/log.out" filePattern="e:/app-%d{yyyy-MM-dd_HH-mm}-%i.out">
    <PatternLayout>
        <Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern>
    </PatternLayout>
    <Policies>
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <CronTriggeringPolicy schedule="0 0 * * * ?"/>
        <SizeBasedTriggeringPolicy size="100 kb"/> 
    </Policies>
    <DefaultRolloverStrategy max="5"/>
</RollingFile> name:表示滾動文件Appender的名稱,<logger>中會依賴此名稱,起名沒有具體要求,但最好簡明直譯; fileName:表示當前日誌所在的日誌文件名稱; filePattern:表示滾動日誌的文件名稱模板,當日志文件進行滾動後,滾動後的文件按照此模板進行命名; PatternLayout--pattern:同上; Policies:表示日誌文件滾動策略; Policies -- TimeBasedTriggeringPolicy:表示日誌文件按照時間間隔來進行滾動; Policies -- CronTriggeringPolicy:表示日誌文件按照設置的時間點來進行滾動; Policies -- SizeBasedTriggeringPolicy:表示日誌文件按照文件大小來進行滾動; DefaultRolloverStrategy:表示log4j2進行滾動後保存的日誌文件數量,默認爲7個;

5.TimeBasedTriggeringPolicy

<TimeBasedTriggeringPolicy interval="1" modulate="true"/> TimeBasedTriggeringPolicy表示按照時間間隔來進行日誌文件的滾動,間隔單位能夠是分鐘、小時,具體須要根據filePattern的格式來進行判別; 例如filePattern="e:/app-%d{yyyy-MM-dd_HH-mm}-%i.out",則表示mm(分鐘)爲單位; interval:表示分隔日誌的時間間隔大小,若是時間間隔單位是分鐘,則表示相隔1分鐘、10分鐘等進行一第二天志分隔; modulate:表示是否對分隔時間進行調製;若是設置爲true則表示分隔的時間從天天的0點、每小時的0分鐘開始進行計算,每間隔多久進行一次切割;好比,modulate=true,interval=4hours,那麼假設上次封存日誌的時間爲03:00,則下次封存日誌的時間爲04:00,以後的封存時間依次爲08:00,12:00,16:00。。。

6.CronTriggeringPolicy

<CronTriggeringPolicy schedule="0 0 * * * ?"/> CronTriggeringPolicy表示按照Cron表達式設置的時間點進行切割日誌; schedule:表示設置的cron表達式;

7.SizeBasedTriggeringPolicy

<SizeBasedTriggeringPolicy size="100 kb"/> SizeBasedTriggeringPolicy表示按照規定的日誌文件大小進行切割日誌; size:表示進行切割日誌文件大小的極值,當日志文件大小知足size的值時,就會進行日誌的切割;

    DefaultRolloverStrategy

<DefaultRolloverStrategy max="5"/> DefaultRolloverStrategy表示log4j2每單位時間內最多能保存多少個日誌切割文件,通常與SizeBasedTriggeringPolicy結合使用; max:表示保存的最大值,默認爲7; 例如:你的log4j2.xml設置以下:fileName="e:/log.out" filePattern="e:/app-%d{yyyy-MM-dd_HH-mm}-%i.out" 那麼在每分鐘內,你能夠保留2個日誌切割文件,多餘的日誌進行覆蓋;

8.Appenders -- Async

<Async name="Async">
    <AppenderRef ref="File"/>
</Async> name:表示異步Appender的名稱,<logger>中會依賴此名稱,起名沒有具體要求,但最好簡明直譯; 異步Appender使用消費者生產者模式進行日誌信息的打印,適用於併發量較大的狀況;

9.PatternLayout

<PatternLayout>
    <Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern>
</PatternLayout> Pattern:設置輸出的日誌信息格式;具體格式以下: %d{yyyy-MM-dd HH:mm:ss, SSS} : 日誌生產時間 %t : 線程名稱 %p : 日誌級別 %level : 日誌級別 %c : logger的名稱 %logger : logger的名稱 %C : Java類名 %m : 日誌內容 %n : 換行符 %L : 日誌輸出所在行數 %M : 日誌輸出所在方法名

10.Loggers -- Logger

<Logger name="com.jiaboyan.logDemo.log4j2Demo" level="info" additivity="false">
    <AppenderRef ref="File"/>
</Logger><Loggers>節點下,對某個類單獨進行日誌配置,即可使用<logger>節點; 上例中,咱們對名稱爲com.jiaboyan.logDemo.log4j2Demo的類進行日誌配置。 level指定級別,additivity表示是否向上傳遞打印日誌信息(若爲true則向上傳遞,那麼root根對象也會進行日誌打印);

11.Loggers -- Root

<Root level="info" >
    <AppenderRef ref="Async"/>
    <AppenderRef ref="File"/>
    <AppenderRef ref="Console"/>
</Root> Root根日誌節點,指定具體的日誌級別,以及使用何種Appender進行日誌輸出;

12.Loggers -- AsyncRoot

<AsyncRoot level="info" includeLocation="false">
    <AppenderRef ref="File"/>
</AsyncRoot> 若是想使用異步logger,還須要在pom.xml中添加disruptor的依賴。 includeLocation結合異步logger使用,當其設置爲true時,纔會顯示具體的行號,以及日誌所在的類名; 若是設置爲false,哪怕<Pattern>設置了輸出行號也不會顯示出來;
參考:https://www.jianshu.com/p/474eaecac699
相關文章
相關標籤/搜索