Log4j2 打印日志實踐


Apache Log4j 是一個基於 Java 的日志記錄工具。它是由瑞士程序員 Ceki Gülcü 於 2001 年開發的,現在則是Apache軟件基金會的一個項目。 Log4j是幾種Java日志框架之一。Log4j 團隊創建了 Log4j 的繼任者,版本號為 2.0 的新版本。Log4j 2.0 着重於 Log4j 1.2、1.3、java.util.logging 和logback中的問題,並解決這些框架中的架構問題。此外,Log4j 2.0 提供了一個插件架構,這使得其更可擴展。Log4j 2.0 不是與 1.x 向后兼容的版本。
—— wikipedia

日志系統在整個項目架構設計中占得比例很重,比如管理員操作記錄,一些捕獲的異常記錄等等。這時候有一個好的日志框架就是我們所必須的。目前最流行的是 Log4j 2.0 版本雖然前一段時間出了一個 0day 的 BUG 但是瑕不掩瑜。Log4j2 的配置也比較簡單,支持 yml 、xml 甚至是 json 都是可以的。這個實踐中我用的是 xml 格式,畢竟其他的沒用過。

先來看下整體的配置,然后在根據每個標簽單獨研究。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" name="log4j2-name" monitorInterval="5">
    <Properties>
        <Property name="console.pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} - [%t] %-5level %logger{36} - %msg%n</Property>
        <Property name="file.pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} - [%t] %-5level %logger{36} - %msg%n</Property>
    </Properties>

    <Appenders>
        <Console name="console-appender" target="SYSTEM_OUT">
            <PatternLayout pattern="${console.pattern}"/>
        </Console>

        <File name="files-appender" fileName="logs/files-appender.log" append="false">
            <PatternLayout>
                <Pattern>${file.pattern}</Pattern>
            </PatternLayout>
        </File>

        <Async name="async-appender">
            <AppenderRef ref="files-appender"/>
        </Async>

        <RandomAccessFile name="random-access-file-appender" fileName="logs/random-access-file.log">
            <PatternLayout>
                <Pattern>${file.pattern}</Pattern>
            </PatternLayout>
        </RandomAccessFile>

        <RollingFile name="rolling-file-appender" fileName="logs/rolling-file-appender.log"
                     filePattern="logs/rolling-file-appender-INFO-%d{yyyy-MM-dd}_%i.log.gz">
            <PatternLayout>
                <Pattern>${file.pattern}</Pattern>
            </PatternLayout>

            <Policies>
                <TimeBasedTriggeringPolicy interval="1"/>
                <SizeBasedTriggeringPolicy size="1MB"/>
            </Policies>
        </RollingFile>

        <RollingRandomAccessFile name="rolling-random-access-file-appender"
                                 fileName="logs/rolling-random-access-file.log"
                                 filePattern="logs/$${date:yyyy-MM}/rolling-random-access-file-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout>
                <Pattern>${file.pattern}</Pattern>
            </PatternLayout>

            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="1 MB"/>
            </Policies>
        </RollingRandomAccessFile>

        <!-- to 收件者 from 寄件者  -->
        <SMTP name="mail-appender" subject="錯誤日志信息" to="發送到哪里" from="發送者"
              smtpHost="smtp.qiye.163.com"
              smtpPort="465"
              bufferSize="1"
              smtpUsername="SMTP用戶名"
              smtpPassword="SMTP密碼"
              smtpProtocol="smtps"
              mail.smtp.ssl.enable="true"
              mail.smtp.starttls.enable="true"
        >
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout>
                <Pattern>${file.pattern}</Pattern>
            </PatternLayout>
        </SMTP>

    </Appenders>
    <Loggers>
				<logger name="org.mybatis" level="INFO"></logger>
        <Root level="info">
            <AppenderRef ref="console-appender"/>
            <!--            <AppenderRef ref="file-appender"/>-->
            <AppenderRef ref="rolling-file-appender"/>
            <AppenderRef ref="async-appender"/>
            <AppenderRef ref="random-access-file-appender"/>
            <AppenderRef ref="rolling-random-access-file-appender"/>
            <AppenderRef ref="mail-appender"/>
        </Root>
    </Loggers>
</Configuration>

上面是我常用的幾個標簽,每個標簽都有其各自的意義。

Configuration

整個配置中最核心的標簽,他對應 log4j 的 ConfigurationFactory 因為我用的是 xml 所以 ConfigurationFactory 會把配置傳遞給 XmlConfigurationFactory ,最常用的標簽就是下面這些。

屬性名稱 描述
name 配置的名稱。
status 日志的等級,有"off", "trace", "debug", "info", "warn", "error", "fatal" 和 "all" ,選擇 "trace" 就可以把 Log4j 的日志也顯示出來
monitorInterval 每隔多少秒更新日志的配置信息

Properties & Property

properties 這個標簽很簡單就是一個屬性標簽可以配置一些全局的屬性,可以給后面的標簽使用。

<Properties>
    <Property name="屬性名稱"></Property>
</Properties>

Appenders

Appenders 單獨沒有什么作用,主要是他的各種子標簽。下面子標簽的屬性是我常用的一些,如果不常用的可能沒有列出來。

  • Console 日志通過控制台打印

    Parameter Name Type Description
    layout Layout 輸出格式化,可以使用 PatternLayout 標簽替代
    name String 標識符
    target String "SYSTEM_OUT" or "SYSTEM_ERR". 默認為 "SYSTEM_OUT".
    <Console name="console-appender" target="SYSTEM_OUT">
        <!--PatternLayout: 輸出日志的格式-->
        <PatternLayout pattern=" %msg%n"/>
    		<!--ThresholdFilter :日志輸出過濾-->
        <!--level="info" :日志級別,onMatch="ACCEPT" :級別在info之上則接受,onMismatch="DENY" :級別在info之下則拒絕-->
        <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
    </Console>
    
  • File 日志通過文件存儲

    Parameter Name Type Description
    append boolean 如果為 true ( 默認值),則記錄將追加到文件末尾。如果設置為 false,則在寫入新記錄之前將清除該文件。
    bufferedIO boolean 當 true 時 - 默認值,記錄將寫入緩沖區,並在緩沖區已滿時將數據寫入磁盤,或者,如果設置了立即Flush,則在寫入記錄時將數據寫入磁盤。文件鎖定不能與緩沖IO一起使用。性能測試表明,即使啟用了即時浮現,使用緩沖 I/O 也能顯著提高性能。
    bufferSize int 當 bufferedIO 為 true 時,可以配置此項的緩沖區大小,默認值為 8192 字節。
    fileName String 寫入文件的名稱,如果文件或者目錄不存在會創建生成
    name String Appender 標識符
    <File name="files-appender" fileName="logs/files-appender.log" append="false">
     <!--PatternLayout: 輸出日志的格式 這種寫法和上面那個等同-->
        <PatternLayout>
            <Pattern>${file.pattern}</Pattern>
        </PatternLayout>
    </File>
    
  • Async 和其他的 Appenders 配合使用,可以使得 Appenders 變為異步處理

    Parameter Name Type Description
    name String 標識符
    <Async name="async-appender">
    		<!--AppenderRef: 引用其他的 appender 使其成為異步處理-->
    		<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
        <AppenderRef ref="files-appender"/>
    </Async>
    
  • RandomAccessFileFile 是一樣的只不過 RandomAccessFile 是始終是緩沖的而且不能關閉。據官方測量性能比 File 開啟 bufferedIO 還要快 200%。內部使用的機制是 ByteBuffer + RandomAccessFile 而不是BufferedOutputStream

    Parameter Name Type Description
    append boolean 如果為 true ( 默認值),則記錄將追加到文件末尾。如果設置為 false,則在寫入新記錄之前將清除該文件。
    fileName String 要寫入的文件的名稱。如果文件或其任何父目錄不存在,則將創建它們。
    bufferSize int 緩沖區大小默認為 262144 字節 (256 * 1024)。
    name String 標識符
    <RandomAccessFile name="random-access-file-appender" fileName="logs/random-access-file.log">
        <PatternLayout>
            <Pattern>${file.pattern}</Pattern>
        </PatternLayout>
    		<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
    </RandomAccessFile>
    
    
  • RollingFile 是一個 OutputStreamAppender,它寫入 fileName 參數中指定的 File,並根據 TriggeringPolicy 和 RolloverPolicy 滾動文件。

    Parameter Name Type Description
    append boolean 如果為 true ( 默認值),則記錄將追加到文件末尾。如果設置為 false,則在寫入新記錄之前將清除該文件。
    bufferedIO boolean 當 true 時 - 默認值,記錄將寫入緩沖區,並在緩沖區已滿時將數據寫入磁盤,或者,如果設置了立即Flush,則在寫入記錄時將數據寫入磁盤。文件鎖定不能與緩沖IO一起使用。性能測試表明,即使啟用了即時浮現,使用緩沖 I/O 也能顯著提高性能。
    bufferSize int 當 bufferedIO 為 true 時,可以配置此項的緩沖區大小,默認值為 8192 字節。
    fileName String 要寫入的文件的名稱。如果文件或其任何父目錄不存在,則將創建它們。
    name String 標識符
    <RollingFile name="rolling-file-appender" fileName="logs/rolling-file-appender.log"
                 filePattern="logs/rolling-file-appender-INFO-%d{yyyy-MM-dd}_%i.log.gz">
        <PatternLayout>
            <Pattern>${file.pattern}</Pattern>
        </PatternLayout>
    		<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
        <Policies>
    				<!-- TimeBasedTriggeringPolicy :時間滾動策略,默認0點小時產生新的文件
    						,interval="6" : 自定義文件滾動時間間隔,每隔6小時產生新文件, 
    						modulate="true" : 產生文件是否以0點偏移時間,即6點,12點,18點,0點-->
            <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
    				<!-- SizeBasedTriggeringPolicy: 當文件超過設定的大小就開始滾動-->
            <SizeBasedTriggeringPolicy size="1MB"/>
        </Policies>
    </RollingFile>
    
  • RollingRandomAccessFileRollingFile 是一樣的,性能和 RandomAccessFile 差不多

    Parameter Name Type Description
    append boolean 如果為 true ( 默認值),則記錄將追加到文件末尾。如果設置為 false,則在寫入新記錄之前將清除該文件。
    fileName String 要寫入的文件的名稱。如果文件或其任何父目錄不存在,則將創建它們。
    bufferSize int 當 bufferedIO 為 true 時,可以配置此項的緩沖區大小,默認值為 8192 字節。
    name String 標識符
  • SMTP 通過郵箱發送日志信息

    Parameter Name Type Description
    name String 標識符
    from String 寄件者郵箱地址
    replyTo String 以逗號分隔的接受者郵箱地址
    to String 接受者郵箱地址
    subject String 郵件的標題
    bufferSize integer 當 bufferedIO 為 true 時,可以配置此項的緩沖區大小,默認值為 512。
    smtpHost String SMTP HOST
    smtpPassword String SMTP 密碼
    smtpPort integer SMTP 端口
    smtpProtocol String SMTP 傳輸協議 smtps 或 smtp 默認是 smtp
    smtpUsername String smtp 用戶名
    <SMTP name="mail-appender" subject="錯誤日志信息" to="發送到哪里" from="發送者"
            smtpHost="smtp.qiye.163.com"
            smtpPort="465"
            bufferSize="1"
            smtpUsername="SMTP用戶名"
            smtpPassword="SMTP密碼"
            smtpProtocol="smtps"
            mail.smtp.ssl.enable="true"
            mail.smtp.starttls.enable="true"
      >
          <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
    			
          <PatternLayout>
              <Pattern>${file.pattern}</Pattern>
          </PatternLayout>
      </SMTP>
    

    配置 SMTP 之后報錯

    main ERROR Could not create plugin of type class org.apache.logging.log4j.core.appender.SmtpAppender for element
     SMTP: java.lang.NoClassDefFoundError: javax/mail/Authenticator java.lang.NoClassDefFoundError: 
    javax/mail/Authenticator 
    

    是應為沒有找到 javax.mail 導入下面坐標即可。

    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.5.0-b01</version>
    </dependency>
    

Loggers

<Loggers>
		<logger name="org.springframework" level="INFO"></logger>
    <Root level="info">
        <AppenderRef ref="console-appender"/>
        <!--            <AppenderRef ref="file-appender"/>-->
        <AppenderRef ref="rolling-file-appender"/>
        <AppenderRef ref="async-appender"/>
        <AppenderRef ref="random-access-file-appender"/>
        <AppenderRef ref="rolling-random-access-file-appender"/>
        <AppenderRef ref="mail-appender"/>
    </Root>
</Loggers>

使用 Logger 配置各種 Appenders ,Logger 必須指定一個包路徑。還可以給這個包設置一個日志等級(TRACE、DEBUG、INFO、WARN、ERROR、ALL 或 OFF)。比如上面的 org.springframework ,如果未指定等級,默認為 ERROR。如果在標簽內設置 additivity 屬性如果為 true 則被該標簽捕獲的內容不會出現在 Root 節點。

<logger name="org.springframework" level="INFO"></logger>

Logger 也可以使用 AppenderRef 標簽來指定輸出位置和日志等級

<logger name="org.springframework" level="INFO">
		<AppenderRef ref="console-appender" level="error"/>
</logger>

沒有使用 logger 標簽捕獲到的內容或者沒有設置additivity 為 true 的日志會出現在 Root 節點, Root 節點沒有 additivity。

<Root level="info">
    <AppenderRef ref="console-appender"/>
    <!--            <AppenderRef ref="file-appender"/>-->
    <AppenderRef ref="rolling-file-appender"/>
    <AppenderRef ref="async-appender"/>
    <AppenderRef ref="random-access-file-appender"/>
    <AppenderRef ref="rolling-random-access-file-appender"/>
    <AppenderRef ref="mail-appender"/>
</Root>

PatternLayout

上面一直出現的 PatternLayout 標簽很明顯是日志輸出的格式。官方有一套自己的格式非常多,非常豐富。

  %d:發生時間,%d{yyyy-MM-dd HH:mm:ss,SSS},輸出類似:2020-02-20 22:10:28,921
	%F:輸出所在的類文件名
	%t:線程名稱
	%p:日志級別
	%c:日志消息所在類名
	%m:消息內容
	%M:輸出所在函數名
	%x: 輸出和當前線程相關聯的NDC(嵌套診斷環境),尤其用到像java servlets這樣的多客戶多線程的應用中。
	%l:執行的函數名(類名稱:行號)com.core.LogHelper.aroundService(LogHelper.java:32)
	%n:換行
	%i:從1開始自增數字
	%-5level:輸出日志級別,-5表示左對齊並且固定輸出5個字符,如果不足在右邊補0
	${sys:user.home}是HOME目錄 如:C:\Users\heave, 此處指定任意目錄如:D:\logs
	%highlight{} 高亮顏色 如:%highlight{%d [%t]}
	%style{%d [%t]}{black} 設置高亮顏色 Red	Green	Yellow	Blue	Magenta	Cyan	White 還有一個 bold 高亮和其他顏色配合使用

例如: [%d{yyyy-MM-dd HH:mm:ss} %p][%c]: %m%n

更詳細的可以查看官方手冊 https://logging.apache.org/log4j/2.x/manual/layouts.html

部分內容來自:

[1]Log4j2 官網 https://logging.apache.org/log4j/2.x/

[2]Log4j2中文文檔 https://www.docs4dev.com/docs/zh/log4j2/2.x/all/


免責聲明!

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



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