首頁 > 軟體

SpringBoot應用自定義logback紀錄檔詳解

2022-10-10 14:01:33

概述

預設情況下,SpringBoot內部使用logback作為系統紀錄檔實現的框架,將紀錄檔輸出到控制檯,不會寫到紀錄檔檔案。如果在application.properties或application.yml設定,這樣只能設定簡單的場景,儲存路徑、紀錄檔格式等。複雜的場景(區分 info 和 error 的紀錄檔、每天產生一個紀錄檔檔案等)滿足不了,只能自定義組態檔logback-spring.xml或者logback.xml。本篇文章主要講解下如何自定義logabck.xml以及對logback檔案中設定做一個詳解。

logback設定詳解

首先我們先了解下logback。

logback 主要分為三個模組:

  • logback-core:是其他兩個模組的基礎模組
  • logback-classic:是對 core 模組的擴充套件,相當於 log4j 的改良版。classic 模組實現了 Slf4j 的 API 因此可以便於和其他紀錄檔框架直接切換
  • logback-access:與Servlet容器整合,以提供http存取紀錄檔功能。

官網設定檔案地址:https://logback.qos.ch/manual/configuration.html

設定內容概念介紹

Logger Context

LoggerContext負責製造logger,也負責以樹結構排列各logger。其他所有logger也通過org.slf4j.LoggerFactory 類的靜態方法getLogger取得。 getLogger方法以 logger名稱為引數。

Logger

Logger作為紀錄檔的記錄器,把它關聯到應用的對應的context上後,主要用於存放紀錄檔物件,也可以定義紀錄檔型別、級別。

Appender

Appender主要用於指定紀錄檔輸出的目的地,目的地可以是控制檯、檔案、遠端通訊端伺服器、 MySQL、PostreSQL、 Oracle和其他資料庫、 JMS和遠端UNIX Syslog守護行程等。

Layout

負責把事件轉換成字串,格式化的紀錄檔資訊的輸出。

設定介紹

組態檔的基本結構:以開頭,後面有零個或多個元素,有零個或多個元素,有最多一個元素。

預設設定的步驟

  • 嘗試在 classpath下查詢檔案logback-test.xml;
  • 如果檔案不存在,則查詢檔案logback.xml;
  • 如果兩個檔案都不存在,logback用BasicConfigurator自動對自己進行設定,這會導致記錄輸出到控制檯。
<?xml version="1.0" encoding="UTF-8"?>
<!-- scan:當此屬性設定為true時,組態檔如果發生改變,將會被重新載入,預設值為true。 scanPeriod:設定監測組態檔是否有修改的時間間隔,如果沒有給出時間單位,預設單位是毫秒。當scan為true時,此屬性生效。預設的時間間隔為1分鐘。 
    debug:當此屬性設定為true時,將列印出logback內部紀錄檔資訊,實時檢視logback執行狀態。預設值為false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!-- 執行環境,dev:開發,test:測試,pre:預生產,pro:生產 -->
    <property name="system_host" value="dev" />
    <property file="system.properties" />
    <!-- 上下文變數設定,用來定義變數值,其中name的值是變數的名稱,value的值時變數定義的值。 通過<property>定義的值會被插入到logger上下文中。定義變數後,可以使「${}」來使用變數。 -->
    <property name="CONTEXT_NAME" value="logback-test" />
    <!-- 紀錄檔檔案存放路徑設定,絕對路徑 -->
    <property name="logs.dir" value="/opt/logs" />
    <!-- 紀錄檔檔案存放路徑設定,tomcat路徑 -->
    <property name="logs.dir" value="${catalina.base}/logs" />
    <!-- 定義紀錄檔檔案 相對輸入位置 -->  
    <property name="log_dir" value="log" />
    <!-- 紀錄檔輸出格式設定 -->
    <!-- 
    %d{yyyy-MM-dd HH:mm:ss} [%level] - %msg%n
      Logger: %logger
      Class: %class
      File: %file
      Caller: %caller
      Line: %line
      Message: %m
      Method: %M
      Relative: %relative
      Thread: %thread
      Exception: %ex
      xException: %xEx
      nopException: %nopex
      rException: %rEx
      Marker: %marker
      newline:%n
    -->
    <property name="CUSTOM_LOG_PATTERN"
        value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{90} - %msg%n" />
    <!-- 上下文名稱:<contextName>, 每個logger都關聯到logger上下文, 預設上下文名稱為「default」。但可以使用<contextName>設定成其他名字,用於區分不同應用程式的記錄。 
        一旦設定,不能修改。 -->
    <contextName>${CONTEXT_NAME}</contextName>
    <!-- <appender>是<configuration>的子節點,是負責寫紀錄檔的元件。 有兩個必要屬性name和class。 name指定appender名稱, 
        class指定appender的實現類。 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 對紀錄檔進行格式化。 -->
        <encoder>
            <pattern>${CUSTOM_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <appender name="file"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 按天來回滾,如果需要按小時來回滾,則設定為{yyyy-MM-dd_HH} -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>log/testC.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 如果按天來回滾,則最大儲存時間為30天,30天之前的都將被清理掉 -->
            <maxHistory>30</maxHistory>
            <!-- 按時間回滾的同時,按檔案大小來回滾 -->
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 過濾器,只記錄WARN級別的紀錄檔 -->
        <!-- 果紀錄檔級別等於設定級別,過濾器會根據onMath 和 onMismatch接收或拒絕紀錄檔。 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 設定過濾級別 -->
            <level>WARN</level>
            <!-- 用於設定符合過濾條件的操作 -->
            <onMatch>ACCEPT</onMatch>
            <!-- 用於設定不符合過濾條件的操作 -->
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 紀錄檔輸出格式 -->
        <encoder>
            <pattern>${CUSTOM_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
	
    <appender name="log_file"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 被寫入的檔名,可以是相對目錄,也可以是絕對目錄,如果上級目錄不存在會自動建立,沒有預設值。 -->
        <file>${logs.dir}/logback-test.log</file>
        <!-- 按照固定視窗模式生成紀錄檔檔案,當檔案大於20MB時,生成新的紀錄檔檔案。視窗大小是1到3,當儲存了3個歸檔檔案後,將覆蓋最早的紀錄檔 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <!-- 必須包含「%i」例如,假設最小值和最大值分別為1和2,命名模式為 mylog%i.log,會產生歸檔檔案mylog1.log和mylog2.log。還可以指定檔案壓縮選項,例如,mylog%i.log.gz 
                或者 沒有log%i.log.zip -->
            <FileNamePattern>${logs.dir}/logback-test.%i.log</FileNamePattern>
            <!-- 視窗索引最小值 -->
            <minIndex>1</minIndex>
            <!-- 視窗索引最大值 -->
            <maxIndex>3</maxIndex>
        </rollingPolicy>
        <!-- 紀錄檔級別過濾器 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 紀錄檔級別過濾器 -->
            <level>INFO</level>
            <!-- 符合要求的紀錄檔級別,過濾,ACCEPT:接受 -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不符合要求的紀錄檔級別,過濾,DENY:拒絕 -->
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 啟用捲動的條件。 -->
        <triggeringPolicy
            class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <!-- 活動檔案的大小,預設值是10MB -->
            <maxFileSize>30MB</maxFileSize>
        </triggeringPolicy>
        <!-- 對記錄事件進行格式化。 -->
        <encoder>
            <pattern>${CUSTOM_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
	
    <!-- 非同步輸出 -->
    <appender name="ASYNC_logback" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丟失紀錄檔.預設的,如果佇列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的紀錄檔 -->
        <!-- <discardingThreshold>0</discardingThreshold> -->
        <!-- 更改預設的佇列的深度,該值會影響效能.預設值為256 -->
        <!-- <queueSize>256</queueSize> -->
        <!-- 新增附加的appender,最多隻能新增一個 -->
        <appender-ref ref="log_file" />
    </appender>
    <!-- 指定包輸出路徑 -->
    <!-- 用來設定某一個 包 或者具體的某一個 類 的紀錄檔列印級別、以及指定<appender>, name:用來指定受此logger約束的某一個包或者具體的某一個類。 
        level:用來設定列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,還有一個特俗值INHERITED或者同義詞NULL,代表強制執行上級的級別。如果未設定此屬性,那麼當前loger將會繼承上級的級別。 
        additivity:是否向上級logger傳遞列印資訊。預設是true。(這個logger的上級就是上面的root) <logger>可以包含零個或多個<appender-ref>元素,標識這個appender將會新增到這個logger。 -->
    <logger name="org.logback.test" level="DEBUG" additivity="true">
        <appender-ref ref="stdout" />
    </logger>
    <!-- 特殊的<logger>元素,是根logger。只有一個level屬性,應為已經被命名為"root". level:設定列印級別,大小寫無關:TRACE, 
        DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能設定為INHERITED或者同義詞NULL。預設是DEBUG。 <root>可以包含零個或多個<appender-ref>元素,標識這個appender將會新增到這個loger。 -->
    <root>
        <level value="WARN" />
        <!-- if表示式,需要Janino jar -->
        <!-- Janino 2.6.0版本開始,除了janino.jar之外, commons-compiler.jar也需要在類路徑中 -->
        <if condition='property("system_host").contains("dev")'>
            <then>
                <appender-ref ref="stdout" />
            </then>
        </if>
        <appender-ref ref="file" />
    </root>
</configuration>

SpringBoot中自定義logback

SpringBoot啟用自定義logback有3種方式:

  • classpath下存在logback-spring.xml
  • classpath下有logback.xml
  • 組態檔中通過設定項指定檔案:logging.config: ./logback-rule.xml

如果可能,我們建議您為紀錄檔記錄設定使用-spring變體或者通過設定項的方式(例如,logback-spring.xml而不是logback.xml)。如果使用標準設定,Spring不能完全控制紀錄檔初始化。

我們本例使用logback-spring.xml作為組態檔演示。

在 src/main/resources 下建立 logback-spring.xml 檔案,分開記錄系統輸出紀錄檔和Error紀錄檔。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <!--彩色紀錄檔輸出格式-->
    <property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%level){blue} %clr(${PID}){magenta} %clr([%thread]){orange} %clr(%logger){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
    <!--非彩色紀錄檔輸出格式-->
    <property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />

    <!--dev檔案路徑:src同級目錄logs,如果上級目錄不存在會自動建立-->
    <property name="DEV_FILE_PATH" value="./logs" />
    <!-- pro檔案路徑 -->
    <property name="PRO_FILE_PATH" value="./logs-prod" />

    <!-- 控制檯輸出 -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- 按照每天生成輸出紀錄檔檔案 -->
    <appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <!--格式化輸出:%d表示日期,%thread表示執行緒,%-5level:級別從左顯示五個字元寬度,%logger{36}:logger是class的全名,後面的數位代表限制最長的字元,%msg:紀錄檔訊息,%n換行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
        <!--捲動策略按照時間捲動-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- rollover daily 檔名稱 -->
            <fileNamePattern>${DEV_FILE_PATH}/output-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- each file should be at most 10MB, keep 60 days worth of history, but at most 2GB -->
            <!--單個檔案大小-->
            <maxFileSize>10MB</maxFileSize>
            <!--紀錄檔檔案保留天數-->
            <maxHistory>60</maxHistory>
            <!--用來指定紀錄檔檔案的上限大小,到了這個值就會刪除舊紀錄檔-->a
            <totalSizeCap>2GB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <!-- 按照每天生成錯誤紀錄檔檔案 -->
    <appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 此紀錄檔檔案只記錄ERROR級別的 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
        <!--輸出紀錄檔到src同級目錄logs中的error.log檔案中-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--基於大小和時間的輪轉策略,當紀錄檔內容超出檔案大小限制後,會自動生成一個檔案來繼續記錄和重新命名-->
            <fileNamePattern>${DEV_FILE_PATH}/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- each file should be at most 10MB, keep 60 days worth of history, but at most 2GB -->
            <maxFileSize>10MB</maxFileSize>
            <maxHistory>60</maxHistory>
            <totalSizeCap>2GB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <root level="INFO">
        <appender-ref ref="consoleAppender" />
        <appender-ref ref="fileAppender" />
        <appender-ref ref="errorAppender" />
    </root>

</configuration>

java中列印紀錄檔:

@SpringBootApplication
@Slf4j
public class LogbackApp {

    public static void main(String[] args) {
        SpringApplication.run(LogbackApp.class, args);

        log.trace("Trace 紀錄檔...");
        log.debug("Debug 紀錄檔...");
        log.info("Info 紀錄檔...");
        log.warn("Warn 紀錄檔...");
        log.error("Error 紀錄檔...");
    }
}

輸出結果:

SpringBoot官方建議使用logback-spring.xml作為logback框架的自定義紀錄檔組態檔,使用logback-spring.xml而不是logback.xml,因為帶-spring字尾的組態檔可以使用一些擴充套件的功能。

多環境輸出紀錄檔檔案

Logback 組態檔中的 節點指令允許您根據組態檔啟用引數(active) 選擇性的包含和排查部分設定資訊。根據不同環境來定義不同的紀錄檔輸出,在 logback-spring.xml中使用 節點來定義,方法如下:

<!--開發環境:列印控制檯-->
    <springProfile name="dev">
        <root level="DEBUG">
            <appender-ref ref="consoleAppender" />
            <appender-ref ref="fileAppender" />
            <appender-ref ref="errorAppender" />
        </root>
    </springProfile>
 
    <!--生產環境:輸出到檔案-->
    <springProfile name="prod">
        <root level="INFO">
            <appender-ref ref="consoleAppender" />
            <appender-ref ref="fileAppender" />
            <appender-ref ref="errorAppender" />
        </root>
    </springProfile>

組態檔新增設定項:

結果:

列印出了debug紀錄檔,說明dev的設定生效了。

讀取組態檔設定

本文通過讀取組態檔中的設定修改輸出的紀錄檔檔名來演示。

1.組態檔中新增設定項

2.logback-spring.xml中新增設定內容如下:

<springProperty scope="context" name="logFileName" source="log.file.name"
        defaultValue="output"/>
  • scope: 使用範圍
  • name: 變數名
  • source: 讀取的設定項名
  • defaultValue: 預設名稱

3.通過${....}使用設定

4.結果,成功修改了輸出的紀錄檔檔名

文章程式碼地址:https://github.com/alvinlkk/springboot-demo/tree/master/springboot-log-logback

以上就是SpringBoot應用自定義logback紀錄檔詳解的詳細內容,更多關於SpringBoot應用自定義logback紀錄檔的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com