1. 程式人生 > >log4j2.xml配置檔案元素解析

log4j2.xml配置檔案元素解析

log4j2.xml配置檔案元素解析

配置檔案展示

《 monitorInterval="30"作用:30秒進行一次掃描該配置檔案,重新載入一次,不需要重啟專案》
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="erro" monitorInterval="30">
	<Properties>
		<!-- 配置日誌檔案輸出目錄此處定義了變數,後面就可以使用${LOG_HOME}進行引用了 -->
		<Property name="LOG_HOME"> /ccx</Property>
</Properties> <Appenders> <!-- 輸出值控制檯 --> <Console name="Console" target="SYSTEM_OUT"> <!-- 格式化日誌 --> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8" /> </Console> <!-- 輸出到檔案中 採用這個可以將日誌寫到多個檔案中,可以自定義日誌分包、日誌檔案數量控制等。因此建議使用這個 --> <RollingRandomAccessFile name="File" fileName="E:/logs/app.log" filePattern="E:/logs/$${date:HH}/%d{HH}.app.%i.log" immediateFlush="true"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8" /> <Policies> <!--5s 翻滾一次 其實就是每過5s就新建一個日誌檔案,如果filepattern的"E:/logs/$${date:HH}/%d{HH}.app 如果不清楚可以參照下面關於policies解釋 這部分相同,則進行增加i 1 2 3 4 5增加 --> <CronTriggeringPolicy schedule="0/5 * * * * ?" /> <!-- 指單個檔案最大的大小,超過這個容量就進行重新建立日誌檔案。 必須配合上面i使用單位 KBMBGB --> <SizeBasedTriggeringPolicy size="10 MB" /> </Policies> <!-- 控制檔案數量,根據日誌名稱的i值,最大到10,之後就進行覆蓋,預設情況下是7 --> <DefaultRolloverStrategy max="10" /> <Filters> <!-- 注意:配置起來比較亂,建議使用的時候單個使用,並將最後的onMismatch="DENY"這樣就可以 了,做到攔截。同時LevelRangeFilter的日誌輸出範圍為LevelRangeFilter範圍與logger設定的level的交集。 --> <!-- 只允許在每天的 8~8點半 之間輸出日誌 --> <TimeFilter start="08:00:00" end="17:29:30" onMatch="ACCEPT" onMismatch="NEUTRAL" /> <!-- 從大到小:error, warn, info, debug, trace --> <LevelRangeFilter minLevel="error" maxLevel="info" onMatch="ACCEPT" onMismatch="DENY" /> </Filters> </RollingRandomAccessFile> </Appenders> <Loggers> <Logger name="AsyncFileLogger" level="trace" additivity="false"> <AppenderRef ref="Console" /> </Logger> <!-- 以下定義兩個logger,name如果是包名,那麼就 com.haiyang是com.haiyang.controller的父logger,同時root是所有logger的父logger 此時通過在程式碼中Logger logger = (Logger) LogManager.getLogger(getClass().getName());如果該方法類在com.haiyang這個包內, 就會呼叫該包的方法。Logger logger = (Logger) LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);呼叫的是root的logger Logger logger = (Logger) LogManager.getLogger("AsyncFileLogger");可以呼叫上面的那個日誌定義 additivity屬性作用:是否整合父類(父類也進行執行),預設是true<Logger name="com.haiyang.controller" level="trace"> <AppenderRef ref="Console" /> </Logger> <Logger name="com.haiyang" level="trace"> <AppenderRef ref="Console" /> </Logger> --> <Root level="erro"> <AppenderRef ref="File" /> </Root> </Loggers> </Configuration>

log4j2配置檔案整體結構

  • Appdenders部分
    • Appender
      • Filter
      • Layout
      • Policies
      • Strategy
  • Loggers部分
    • Logger
    • Root

對於Appender的理解

作用:簡單說Appender就是一個管道,定義了日誌內容的去向(儲存位置)。

配置一個或者多個Filter ,Filter的過濾機制和Servlet的Filter有些差別,下文會進行說明。(注意只是在檔案輸出的時候才配置 ,因為輸入值控制檯配置該屬性沒意義。)

配置Layout 來控制日誌資訊的輸出格式。

配置Policies 以控制日誌何時(When)進行滾動。通俗的解釋就是控制日誌如何區分。如多長時間進行新建一個資料夾存放日誌,同一資料夾下多長時間生成一個log日誌檔案,統一名稱日誌檔案最多存放幾個,超出之後按照最新的覆蓋最先的。(注意只是在檔案輸出的時候才配置 ,因為輸入值控制檯配置該屬性沒意義。)

配置Strategy 以控制日誌如何(How)進行滾動。(這個沒有做過多的瞭解)

對於Logger的理解

簡單說Logger就是一個路由器,指定類、包中的日誌資訊流向哪個管道,以及控制他們的流量(日誌級別) .通俗的解釋就是,定義哪個名稱、包下日誌應當採用哪種Appender進行輸出。
Appender標籤的實現類
其實這些標籤都是類名或者類名去掉字尾。

Appender的常用的實現類有:

其實Appender相當於是一個介面,在實際使用過程中,都是使用它的實現類,常用的是以下三個實現類。分別對應控制檯輸出 單檔案輸出 多檔案輸出。注意:括號內的名稱為在log4j2.xml檔案中的標籤名。

  1. ConsoleAppender(Console)
  2. FileAppender(File)、RandomAccessFileAppender(RandomAccessFile)
  3. RollingFileAppender(RollingFile)、RollingRandomAccessFileAppender(RollingRandomAccessFile)

標籤詳解及可包含字標籤元素

Console

該實現類會把日誌輸出到控制檯中。
它有兩種輸出方式:

  1. SYSTEM_OUT(System.out) // 預設的配置
  2. SYSTEM_ERR(System.err)
    兩種輸出方式區別,其實就相當於呼叫system.out與呼叫system.err的區別,後置在控制檯輸出的為紅色字型。
    如果不配置,預設使用SYSTEM_OUT進行輸出。括號中是呼叫的方法。
    程式碼如下:
<Appenders>
     <!-- 在log4j2.xml檔案中配置  採用Console標籤即可。-->
        <Console name="Console" target="SYSTEM_OUT">
            <!-- 格式化日誌 -->
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>
        </Console>
 </Appenders> 

File、 RandomAccessFile

相同點:寫入日誌資訊到檔案(單個檔案中)
不同點:使用的I/O實現類不同,前者使用FileOutputStream,後者使用RandomAccessFile。
官方文件說是在bufferedIO=true(預設是true)的情況下後者比前者效能提升20% ~ 200%,不明覺厲,就用後者吧。
通俗點解釋就是:改組是輸出在單個日誌檔案中。平時採用後者居多.

程式碼示例:
<Appenders>
        <RandomAccessFile name="File" fileName="logs/app.log" immediateFlush="false">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>
        </RandomAccessFile>
    </Appenders> 
屬性解釋:

filename:來指定檔案位置,檔案或目錄不存在則會自動建立。通常情況下指定準確的位置,如果不指定碟符,預設位置是開發軟體所在home目錄。具體的不確定,因此建議改為準確的碟符位置,如文章開頭所示例那樣。
immediateFlush:是否每次寫入都要立刻重新整理到硬碟中。預設true,如果使用預設值可能會影響效能。

RollingFile 、 RollingRandomAccessFile

可以進行多個日誌檔案輸出。(重點掌握)
這一對之間的區別與上一對之間的區別是一樣的。平時也是採用RollingRandomAccessFile
上一對的實現類不能進行日誌滾動,所謂日誌滾動就是當達到設定的條件後,日誌檔案進行切分。
比如:工程師想讓系統中的日誌按日進行切分,並且按月歸檔。
這時候這一對的作用就體現出來了。

示例程式碼:
<Appenders>
        <RollingRandomAccessFile name="File" fileName="logs/app.log"
                                 filePattern="logs/$${date:hh-mm}/%d{hh-mm-ss}.app.%i.log" >
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>

            <Policies>
                <!-- 每 5s 翻滾一次 -->
                <CronTriggeringPolicy schedule="0/5 * * * * ?" />
                <SizeBasedTriggeringPolicy size="10 MB"/>
            </Policies>
            
            <DefaultRolloverStrategy max="10" />            
        </RollingRandomAccessFile>

    </Appenders>
 

-注意 filePattern這個屬性,參照上面示例程式碼,是定義日誌名稱的作用,後面的%i的作用,是配合如下policies與DefaultRolloverStrategy使用的。如下配置的fileOattern名稱為logs目錄下,以分鐘為資料夾區分,時分秒為檔名,如果這樣設計,那麼下面policies屬性設5s屬性及DefaultRolloverStrategy屬性將失去作用,因為檔名不會重複。但是如果使用logs/$${date:hh}/%d{hh}.app.%i.log這樣命名,就好很多,因為以小時為檔名,這樣檔案重名的概率就比較大,從而就使用上i的屬性編號。日誌檔案展示如下圖:
在這裡插入圖片描述

只有上圖因為17.app同名,因此此時DefaultRolloverStrategy才能起上作用。一直到建立日誌10次之後 會把舊的日誌內容覆蓋。

Filters

Filters決定日誌事件能否被輸出。過濾條件有三個值:ACCEPT(接受),DENY(拒絕),NEUTRAL(中立)。

常用的Filter實現類有:

  1. LevelRangeFilter 控制輸出日誌級別範圍
  2. TimeFilter 控制日誌按照何種日期進行輸出
  3. ThresholdFilter 平時使用比較少
    使用程式碼如下:
 <Appenders>

        <Console name="Console">

            <!--
                設定 onMismatch="NEUTRAL" 可以讓日誌經過後續的過濾器
                最後一個過濾器建議設定 onMismatch="DENY", 不然日誌就輸出了。
            -->
            <Filters>
                <!-- 從大到小:error, warn, info, debug, trace -->
                <LevelRangeFilter minLevel="error" maxLevel="info" onMatch="ACCEPT" onMismatch="NEUTRAL" />
                <!-- 只允許在每天的 8點~8點半 之間輸出日誌 -->
                <TimeFilter start="08:00:00" end="08:30:00" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>

            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>
        </Console>

    </Appenders>
 

注意:配置起來比較亂,建議使用的時候單個使用,並將最後的onMismatch="DENY"這樣就可以 了,做到攔截。同時LevelRangeFilter的日誌輸出範圍為LevelRangeFilter範圍與logger設定的level的交集。

Policy & Strategy

上文也說了,Policy是用來控制日誌檔案何時(When)進行滾動的;Strategy是用來控制日誌檔案如何(How)進行滾動的。
如果配置的是RollingFile或RollingRandomAccessFile,則必須配置一個Policy。
如果想按月歸檔,按日切分日誌,然後

Policy常用的實現類:

  1. SizeBasedTriggeringPolicy
  2. CronTriggeringPolicy
  3. TimeBasedTriggeringPolicy
SizeBasedTriggeringPolicy

根據日誌檔案的大小進行滾動。

單位有:KB,MB,GB

CronTriggeringPolicy

使用Cron表示式進行日誌滾動,很靈活。

TimeBasedTriggeringPolicy

這個滾動策略依賴於filePattern中配置的最具體的時間單位,根據最具體的時間單位進行滾動。

這種方式比較簡潔。CronTriggeringPolicy策略更強大。

簡單示例:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration name="baseConf" status="warn" monitorInterval="30">

    <Appenders>

        <RollingRandomAccessFile name="File" fileName="logs/app.log"
                                 filePattern="logs/$${date:hh-mm}/%d{hh-mm-ss}.app.%i.log" >
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" charset="UTF-8"/>

            <Policies>
                <!-- 每 5s 翻滾一次 -->
                <!--<CronTriggeringPolicy schedule="0/5 * * * * ?" />-->
                
                <!-- 
                    filePattern中最具體的時間單位是 秒。
                    這裡用 TimeBasedTriggeringPolicy 替換 CronTriggeringPolicy
                    
                    注意:modulate屬性是指從啟動時間開始算5秒,還是從0秒開始算5秒,執行一下就明白了。
                    modulate: true(預設值) // 會從啟動時間開始算 5秒
                    modulate: false // 從 0秒開始算
                -->
                <TimeBasedTriggeringPolicy interval="5" modulate="true"/>
                
                <SizeBasedTriggeringPolicy size="10 MB"/>
            </Policies>
            
            <DefaultRolloverStrategy max="10" />
            
        </RollingRandomAccessFile>

    </Appenders>

    <Loggers>

        <Root level="info">
            <AppenderRef ref="File"/>
        </Root>

    </Loggers>

</Configuration>

Strategy常用的實現類

  1. DefaultRolloverStrategy
  2. DirectWriteRolloverStrategy
    這兩個Strategy都是控制如何進行日誌滾動的,至於他們的區別我還是不太明白,大佬解釋一下吧。平時大部分用DefaultRolloverStrategy就可以了。

Logger

Logger部分就比較簡單了,分為兩個Logger:

  1. Root(必須配置)
  2. Logger

簡單示例:


<?xml version="1.0" encoding="UTF-8"?>
<Configuration name="baseConf" status="warn" monitorInterval="30">

    <Appenders>

        <Console name="Console">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
        </Console>

    </Appenders>

    <Loggers>

        <Root level="trace">
            <AppenderRef ref="Console"/>
            <Filters>
                <LevelRangeFilter minLevel="error" maxLevel="info" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>
        </Root>

    </Loggers>

</Configuration>

注意:Logger中也可以加過濾器的喲~

較重要的問題: 日誌重複列印

這時候我們需要使用一個Logger的屬性來解決,那就是additivity,其預設值為true,需要配置為false。參照上面的示例程式碼。

<Logger name="AsyncFileLogger" level="trace" additivity="false">
			<AppenderRef ref="Console" />
		</Logger>

總結:

其實使用logger日誌,只需關係日誌怎麼使用,日誌輸出位置即可。關於該文章目的就是為了瞭解log4j2.xml檔案的配置方式。以下有幾種經驗。
1.在使用過程中會檢視別人配置檔案 遇到如下圖不知道$${jndi:logging/context-name}是什麼意思,此時解決方法就是,在log日誌中,將這個變數輸出,看一下到底是什麼,就知道是什麼值了。同樣,有時候會在filename等屬性中也會遇到類似這種不知道的值,解決方案也如此。
在這裡插入圖片描述
2.在配置檔案中自己定義屬性。並在配置檔案中進行引用。
在這裡插入圖片描述
3.關於注意 大寫HH為24小時制,hh為12小時制,這與java日期格式一致。
在這裡插入圖片描述
4.關於控制jar包及框架日誌情況,只需要開啟包名即可 如下程式碼spring框架日誌。

<Loggers>
        
        <!-- 
            限制Spring框架日誌的輸出級別,其它框架類似配置
            或者使用 AppenderRef 標籤,將其輸出到指定檔案中,記得加上 additivity="false"
        -->
        <logger name="org.springframework" level="warn"/>
        <Root level="info">
            <AppenderRef ref="File1"/>
        </Root>

    </Loggers>
 

5.關於lookups的知識,個人覺得不要進行太糾結,鑽死牛角。及日誌輸出格式問題,能顯示出來即可,不需要死記硬背,會用即可。
lookups參考資料:
https://blog.csdn.net/ghsau/article/details/52334762