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

洛神灬殤發表於2022-12-21

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>

相關文章