【Spring專題】「開發指南」夯實實戰基礎功底之解讀logback-spring.xml檔案的詳解實現

2022-12-22 06:00:45

logback的maven設定

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>2.0.3</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.4.4</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-access</artifactId>
    <version>1.4.4</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.4.4</version>
</dependency>

紀錄檔框架層級

根節點: configuration

<configuration scan="true" scanPeriod="60 seconds" debug="false">
  • scan : 當此屬性設定為true時,組態檔如果發生改變,將會被重新載入,預設值為true
  • scanPeriod : 設定監測組態檔是否有修改的時間間隔,如果沒有給出時間單位,預設單位是毫秒。當scan為true時,此屬性生效。預設的時間間隔為1分鐘
  • debug : 當此屬性設定為true時,將列印出logback內部紀錄檔資訊,實時檢視logback執行狀態,預設值為false。

紀錄檔輸出元件

子節點:appender

appender用來格式化紀錄檔輸出節點,有兩個屬性nameclass,class用來指定哪種輸出策略。

總體的層級結構

  • appender:定義appender填充器的名稱和類定義
    • encoder:紀錄檔格式設定定義宣告編碼格式實現類
      • pattern:主要定義紀錄檔輸出的字串格式

常用就是控制檯輸出策略和檔案輸出策略,如下。

ConsoleAppender-控制檯輸出器

ConsoleAppender主要的作用是將紀錄檔資訊列印到控制檯上,更加準確的說:使用System.out或者System.err方式輸出,主要子標籤有:encodertarget這兩個元素標籤,具體案例樣式如下所示。

<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
     <encoder>
         <pattern>%date{"yyyy-MM-dd,HH:mm:ss,SSS"} [%X{TID}] [%thread] %-5level %logger{36} - %msg%n</pattern>
         <charset>UTF-8</charset> <!-- 此處設定字元集 -->
     </encoder>
</appender>

最外面xml標籤(append)裡面定義了對應的append的名稱name,以及(class)對應的實際填充物件類,如下所示。

<appender name="console" class="ch.qos.logback.core.ConsoleAppender">

encoder標籤

  • <encoder>:主要用於定義對應的編碼模式和編碼格式元件的宣告。
  • <pattern>:主要用於定義對應的該encoder下的編碼模式字串,例如:%date{"yyyy-MM-dd,HH:mm:ss,SSS"} [%X{TID}] [%thread] %-5level %logger{36} - %msg%n

內部的格式字元,例如:%date等的相關的格式講解後面的章節會統一詳細的去進行介紹,大家可以根據後面的章節進行學習即可。

FileAppender-檔案輸出器

用於將紀錄檔資訊輸出到檔案中,主要子標籤有:appender,encoder,file,對應的層級關係為:

  • appender:紀錄檔檔案輸出appender物件
    • encoder:紀錄檔格式設定定義宣告編碼格式實現類
      • file:紀錄檔輸出路徑,代表著檔案目錄加檔名稱

appender

同上,依然保持不變的設定模式

  <appender name="file" class="ch.qos.logback.core.FileAppender">
      <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
           <pattern>${pattern}</pattern>
     </encoder>
      <file>${log_dir}/logback.log</file>
 </appender>

encoder標籤

  • <encoder>:主要用於定義對應的編碼模式和編碼格式元件的宣告。
  • <pattern>:主要用於定義對應的該encoder下的編碼模式字串,例如:%date{"yyyy-MM-dd,HH:mm:ss,SSS"} [%X{TID}] [%thread] %-5level %logger{36} - %msg%n

file標籤

  • <file>:紀錄檔輸出路徑,代表著檔案目錄加檔名稱
<file>${log_dir}/logback.log</file>

RollingFileAppender-捲動檔案輸出器

RollingFileAppender是FileAppender的子類,繼承關係。

擴充套件能力

如果滿足一定的條件,能夠動態的建立一個檔案。然後將紀錄檔寫入到新的檔案中。

主要子標籤

file(檔案全路徑),filter(過濾器),encoder(輸出格式化),rollingPolicy(捲動策略),總體的相關案例如下所示。

<appender name="errorLogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_BASE_DIR}/log-error.log</file>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>Error</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_BASE_DIR}/log-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize>
            <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory>
            <totalSizeCap>${LOG_FILE_TOTAL_SIZE_CAP}</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%date{"HH:mm:ss,SSS"} [%X{TID}] [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
</appender>

其中,我們重點需要了解的是filter(過濾器)rollingPolicy(捲動策略)這兩個標籤對應的功能。

filter(過濾器)

過濾器主要分為兩個常用的種類:ThresholdFilter和LevelFilter的過濾器。

系統定義的攔截器(ThresholdFilter)

過濾掉ERROR級別以下的紀錄檔不輸出到檔案中。

<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    <level>ERROR</level>
</filter>
策略攔截器(LevelFilter)

使用匹配規則匹配level,按照規則進行列印,可以避免輸出 Error級別 之外的紀錄檔

<filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--過濾 Error-->
            <level>Error</level>
            <!--匹配到就允許-->
            <onMatch>ACCEPT</onMatch>
            <!--沒有匹配到就禁止-->
            <onMismatch>DENY</onMismatch>
 </filter>
rollingPolicy(捲動策略)

盤點我們常用的策略方式主要就是一下這兩種:

TimeBasedRollingPolicy

它根據時間來制定捲動策略.時間捲動策略可以基於時間捲動按時間生成紀錄檔,無法控制檔案大小。

SizeAndTimeBasedRollingPolicy
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_BASE_DIR}/log-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize>
            <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory>
            <totalSizeCap>${LOG_FILE_TOTAL_SIZE_CAP}</totalSizeCap>
        </rollingPolicy>

基於大小和時間的捲動策略。這個策略出現的原因就是對時間捲動策略的一個補充,使其不僅按時間進行生成而且考慮到檔案大小的原因,因為在基於時間的捲動策略生成的紀錄檔檔案,只是對一段時間總的紀錄檔大小做了限定,但是沒有對每個紀錄檔檔案的大小做限定,這就會造成個別紀錄檔檔案過大,後期傳遞,所以就有了這個策略。

注意:totalSizeCap屬性生效需要logback-classic依賴與logback-core依賴版本大於1.2.0,原因:ch.qos.logback.core.rolling.helper.TimeBasedArchiveRemover類存在計算溢位問題。

子節點:logger

案例設定如下。

 <logger name="com.xx.XXController" level="WARN" additivity="false">
        <appender-ref ref="console"/>
 </logger>
  • name:用來指定受此logger約束的某一個包或者具體的某一個類。
  • level:用來設定列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,還有一個特殊值-INHERITED或者同義詞NULL,代表強制執行上級的級別。如果未設定此屬性,那麼當前logger將會繼承上級的級別。
  • addtivity:是否向上級logger傳遞列印資訊。預設是true。logger最上級為root節點

子節點: root

<root level="debug">
  <appender-ref ref="console" />
  <appender-ref ref="file" />
</root>
  • root節點是必選節點,用來指定最基礎的紀錄檔輸出級別,只有一個level屬性。level預設是DEBUG。
  • level:用來設定列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能設定為INHERITED或者同義詞NULL

屬性節點

定義上下文變數,name變數名稱,value為值。

logback的容器上下文

<property name="LOG-LEVEL" value="INFO" />
... ...
<logger name="com.xx.XXController" level="${LOG-LEVEL}" additivity="false">
        <appender-ref ref="console"/>
 </logger>

應用springboot的環境變數

從springboot設定變數中獲取key為source的值,name變數名稱.

<springProperty scope="context" name="LOG_FILE_MAX_SIZE" source="logging.file.max-size" defaultValue="100MB" />
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize>
</rollingPolicy>
劃分出不同的profile環境下的環境變數
<springProfile name="test">
    <!-- configuration to be enabled when the "test" profile is active -->
</springProfile>
<springProfile name="dev, test">
    <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>
<springProfile name="!prod">
    <!-- configuration to be enabled when the "prod" profile is not active -->
</springProfile>

完整案例

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <springProperty scope="context" name="LOG_FILE_MAX_SIZE" source="logging.file.max-size" defaultValue="100MB" />
    <springProperty scope="context" name="LOG_BASE_DIR" source="logging.file.base-path" defaultValue="/export/Logs/albert.com" />
    <springProperty scope="context" name="LOG_FILE_MAX_HISTORY" source="logging.file.max-history" defaultValue="30" />
    <springProperty scope="context" name="LOG_FILE_TOTAL_SIZE_CAP" source="logging.file.total-size-cap" defaultValue="20GB" />
    <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{TID}] %-5level %logger{36} %F:%L - %msg %ex%n"/>
    <property name="LOG-LEVEL" value="INFO" />
    <!--紀錄檔輸出節點-->
    <appender name="errorLogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--紀錄檔輸出位置-->
        <file>${LOG_BASE_DIR}/logfile-error.log</file>
        <!--紀錄檔級別過濾器-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--過濾 Error-->
            <level>Error</level>
            <!--匹配到就允許-->
            <onMatch>ACCEPT</onMatch>
            <!--沒有匹配到就禁止-->
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--按照大小與時間的策略進行歸檔-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_BASE_DIR}/logfile-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!--歸檔檔案最大大小-->
            <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize>
            <!--歸檔檔案儲存時長,單位天-->
            <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory>
            <!--歸檔檔案總大小約束-->
            <totalSizeCap>${LOG_FILE_TOTAL_SIZE_CAP}</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <!-- 列印紀錄檔格式 PFTID為pFinder的traceId -->
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <!-- 此處設定字元集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!--紀錄檔輸出節點-->
    <appender name="defaultLogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--紀錄檔輸出位置-->
        <file>${LOG_BASE_DIR}/logfile-all.log</file>
        <!--按照大小與時間的策略進行歸檔-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_BASE_DIR}/logfile-all.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!--歸檔檔案最大大小-->
            <maxFileSize>${LOG_FILE_MAX_SIZE}</maxFileSize>
            <!--歸檔檔案儲存時長,單位天-->
            <maxHistory>${LOG_FILE_MAX_HISTORY}</maxHistory>
            <!--歸檔檔案總大小約束-->
            <totalSizeCap>${LOG_FILE_TOTAL_SIZE_CAP}</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <!-- 列印紀錄檔格式 PFTID為pFinder的traceId -->
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <!-- 此處設定字元集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <root level="${LOG-LEVEL}">
        <appender-ref ref="defaultLogFile" />
        <appender-ref ref="errorLogFile" />
    </root>
</configuration>