Java 日誌框架 Logback

Wh1te發表於2018-05-13

Logback 簡介

Logback 是一個穩定、高效、快速的 Java 日誌框架,作為 log4j 的改良版,它與 log4j 相比擁有更多特性,也帶來了很大的效能提升,具體改進可以檢視官方文件

Logback 主要分為三個模組

  • logback-core:核心模組,作為 classic 和 access 模組的基礎
  • logback-classic:實現了 slf4j API,配合 slf4j 使用,可以方便的切換其他日誌框架
  • logback-access:​​與Servlet容器(如Tomcat和Jetty)整合,提供了 HTTP 訪問日誌介面

Logback 載入

Logback 啟動載入時會按一下順序查詢配置檔案

  1. 在系統配置檔案 System Properties 中尋找是否有 logback.configurationFile 對應的 value
  2. 在 classpath 下尋找是否有 logback.groovy(logback支援groovy與xml兩種配置方式)
  3. 在 classpath 下尋找是否有 logback-test.xml
  4. 在 classpath 下尋找是否有 logback.xml

當查詢到任意一項配置存在後就不進行後續掃描了,會使用該配置檔案進行初始化,如果沒有查詢到配置檔案,Logback會建立一個向控制檯輸出日誌的配置。

Logback 配置

根節點 configuration

configuration 是配置檔案的根節點,有三個屬性:

  • debug:預設值為false,設定為true時,將列印出 logback 內部日誌資訊,實時檢視 logback 執行狀態。
  • scan:預設值為true,設定為true時,配置檔案如果發生改變,將會被重新載入。
  • scanPeriod:當 scan 為 true 時,此屬性才會生效。設定掃描配置檔案是否有修改的時間間隔,預設單位是毫秒。預設的時間間隔為1分鐘(60 second)

配置程式碼:

<configuration scan="true" scanPeriod="60 second" debug="true">
</configuration>
複製程式碼

設定上下文名稱 contextName

每個 logger 都關聯到 logger 上下文,預設上下文名稱為 “default”。但可以使用<contextName>設定成其他名字,用於區分不同應用程式的記錄。一旦設定,不能修改。

配置程式碼:

<contextName>new context name</contextName>
複製程式碼

設定變數 property

property 是用來定義變數的標籤,設定之後可以用 ${變數名} 訪問,有三個屬性:

  • name:變數名稱
  • value:變數值
  • file:指定配置檔案的路徑,它的作用在於,如果有多個配置資訊的話,可以直接寫在配置檔案中,然後通過file引入
  • resource:作用與 file 一樣,不同的是它可以直接從 classpath 路徑下引入配置檔案

配置程式碼:

<!-- name value 形式 -->
<property name="APP_Name" value="MyApp"/>
<contextName>${APP_Name}</contextName>  
複製程式碼
<!-- file 形式 -->
variables.properties:
APP_Name=MyApp
LOG_PATH=logs

<property file="src/main/java/config/variables.properties" />
<contextName>${APP_Name}</contextName> 
複製程式碼
<!-- resource 形式 -->
variables.properties:
APP_Name=MyApp
LOG_PATH=logs

<property resource="variables.properties" />
<contextName>${APP_Name}</contextName> 
複製程式碼

configuration 子節點 logger、root

logger 用來設定某一個類或者某個包的日誌輸出級別、以及輸出位置(指定 appender),有三個屬性:

  • name:指定的包名或者類名
  • level:輸出日誌級別,如果未設定此級別,那麼當前 logger 會向上繼承最近一個非空級別,root 預設有一個 level 為 debug
  • additivity:是否將日誌向上級傳遞,預設為 true

logger 通過設定子節點 appender-ref 來指定日誌輸出位置,一個 logger 可以設定多個 appender-ref
配置程式碼:

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>[%d{HH:mm:ss.SSS}] [%5level] [%thread] %logger{36} %msg%n</Pattern>
            <charset>UTF-8</charset>
        </encoder>
</appender>
<logger name="X" level="INFO" additivity="false">
        <appender-ref ref="STDOUT"/>
</logger>
<logger name="X.Y" additivity="false">
    <appender-ref ref="STDOUT"/>
</logger>
複製程式碼

root 是一個特殊的 logger , 是所有 logger 的根節點,因為已經被命名為 root 同時也沒有父級別,所以只有一個屬性 level,預設為 DEBUG
配置程式碼:

<root level="DEBUG">
    <appender-ref ref="STDOUT"/>
    <appender-ref ref="ASYNC"/>
</root>
複製程式碼

level 繼承示例1:

logger name level 實際 level
root DEBUG DEBUG
X 未設定 DEBUG
X.Y 未設定 DEBUG
X.Y.Z 未設定 DEBUG

示例1只有 root 設定了一個級別,X,X.Y 和 X.Y.Z 這三個 logger 未設定日誌輸出級別,因此向上繼承 root 的級別,即 DEBUG

level 繼承示例2:

logger name level 實際 level
root ERROR ERROR
X INFO INFO
X.Y DEBUG DEBUG
X.Y.Z WARN WARN

示例2所有 logger 都設定了一個日誌級別,等級繼承不起作用。

level 繼承示例3:

logger name level 實際 level
root DEBUG DEBUG
X INFO INFO
X.Y 未設定 INFO
X.Y.Z WARN WARN

示例3 X.Y 沒有設定日誌級別,向上繼承最近一個有日誌級別的 logger X 的值。

level 繼承示例4:

logger name level 實際 level
root DEBUG DEBUG
X INFO INFO
X.Y 未設定 INFO
X.Y.Z 未設定 INFO

示例4 X.Y 和 X.Y.Z 沒有設定日誌級別,向上繼承最近一個有日誌級別的 logger X 的值。

configuration 子節點 appender

appender 是負責寫日誌的元件,有兩個屬性(使用時都必須配置):

  • name:設定 appender 的名稱,供後面 logger 設定引用
  • class:設定 appender 的全路徑類名,例:ch.qos.logback.core.ConsoleAppender

appender 可以包含零個或一個 layout ,零個或多個 encoder 元素以及零個或多個 filter 元素。除了這三個元素之外,還可以包含與 appender 類的 JavaBean 屬性相對應的任意數量的元素,如: file 指定日誌檔名稱。

  • layout:對日誌進行格式化
  • encoder: encoder 是0.9.19版本之後引進的,以前的版本使用 layout ,logback極力推薦的是使用 encoder 而不是 layout
  • filter:對日誌進行過濾

appender 常用的有以下幾種:

  1. ConsoleAppender:輸出到控制檯,或者更確切地說是輸出到 System.out 或 System.err,前者是預設目標。
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
    <target>
        System.err
    </target>
</appender>
複製程式碼
  1. FileAppender:輸出到檔案,目標檔案由 file 指定。如果該檔案已存在,則根據 append 屬性的值確定追加或者清空檔案。
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>testFile.log</file>
    <append>true</append>
    <!-- set immediateFlush to false for much higher logging throughput -->
    <immediateFlush>true</immediateFlush>
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
</appender>
複製程式碼
  1. RollingFileAppender:繼承自 FileAppender ,提供了滾動記錄的功能,先將日誌記錄到指定檔案,當觸發某個條件時,將日誌記錄到其他檔案。有兩個重要的子節點 rollingPolicy 和 triggeringPolicy
  • rollingPolicy:指定發生滾動時 RollingFileAppender 的行為,例如可以切換日誌檔案
  • triggeringPolicy:指定 RollingFileAppender 何時觸發滾動。
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logFile.log</file>
    <!-- 根據時間來制定滾動策略,既負責滾動也負責觸發滾動。 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- 每天生成日誌檔案 -->
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>

      <!-- 保留最近30天的日誌檔案 -->
      <maxHistory>30</maxHistory>
      <totalSizeCap>3GB</totalSizeCap>

    </rollingPolicy>

    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
</appender> 

<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>mylog.txt</file>
    <!-- 基於檔案大小和時間的滾動策略 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <!-- 每天生成日誌檔案 -->
      <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
       <!-- 每個日誌檔案最多 100MB, 保留 60 天, 最多 20 GB-->
       <maxFileSize>100MB</maxFileSize>    
       <maxHistory>60</maxHistory>
       <totalSizeCap>20GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
</appender>
複製程式碼
  1. AsyncAppender:非同步記錄日誌,它僅僅作為一個排程者,因此必須引用另一個 appender 來做日誌輸出。
  • discardingThreshold:預設情況下,當阻塞佇列剩餘容量為20%時,它將丟棄級別為 TRACE,DEBUG 和 INFO 的事件,僅保留級別為 WARN 和 ERROR 的事件。設定為0即可保留所有事件。
  • queueSize:阻塞佇列的最大容量。預設情況下,queueSize 為 256。
  • appender-ref:表示 AsyncAppender 使用哪個具體的 appender 進行日誌輸出。
<!-- 非同步輸出 -->  
<appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">  
        <!-- 不丟失日誌 -->  
        <discardingThreshold>0</discardingThreshold>  
        <!-- 更改預設的佇列的深度,該值會影響效能.預設值為256 -->  
        <queueSize>256</queueSize>  
        <!-- 新增附加的appender,最多隻能新增一個 -->  
        <appender-ref ref ="FILE"/>  
</appender>
     
<logger name="X" level="DEBUG">
    <appender-ref ref="ASYNC" />
</logger>
複製程式碼

相關文章