SpringBoot Logback 日誌配置

前言

之前使用 SpringBoot 的時候,總是習慣於將日誌框架切換為 Log4j2,可能是覺得比較靠譜,也可能年齡大了比較排斥新東西。今天搞新項目的時候,想著每次搞這個遷移有點兒麻煩,就想著看看 Logback 這個 SpringBoot 一直默認集成(推薦)使用的框架具體是個什麼樣子,參考Spring 官方文檔日誌章節實踐下來感覺不錯,翻譯和補充一下關鍵知識點。

:本文僅涉及 SpringBoot 和 Logback 集成使用的相關內容,關於 Logback 的詳細內容請自行參考官網

日誌格式

以 SpringBoot 應用啟動的一行日誌為例:

2021-12-08 10:21:45.585  INFO 28453 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)

日誌由以下 8 個部分組成:

  1. 日期時間,精確到毫秒

    2021-12-08 10:21:45.585
    
  2. 日誌級別

    INFO
    

    Logback 的日誌級別:ERROR、WARN、INFO、DEBUG 和 TRACE。注意,Logback 不支援 FATAL,會映射給 ERROR。

  3. 進程ID

    28453
    

    Java(SpringBoot)應用進程ID。

  4. 分隔線

    ---
    

    僅作為日誌頭(1、2、3)和日誌體(5、6、7)之間的分隔線,無實際意義。

  5. 執行緒名稱

    [           main]
    

    方括弧([])內部的字元串即為執行緒名稱。

  6. 記錄器名稱

    o.s.b.w.embedded.tomcat.TomcatWebServer
    

    日誌記錄器(logger)名稱,一般使用類名代替。

  7. 冒號

    :
    

    僅作為日誌記錄器(6)和日誌消息(7)之間的分隔符,無實際意義。

  8. 日誌消息

    Tomcat initialized with port(s): 8080 (http)
    

    日誌消息內容。

日誌輸出

默認情況下,SpringBoot 僅會輸出日誌至控制台(Console),如果需要輸出至日誌文件,需要通過配置屬性 logging.file.name 或 logging.file.path 開啟日誌文件輸出功能。

兩個配置屬性二選一即可,本文以 logging.file.name 為例:

logging:
  file:
    name: /tmp/boot.log

日誌輸出至控制台的同時,也會輸出至日誌文件 /tmp/boot.log,該日誌文件大小達到 10 MB 時,會發生日誌輪替:

boot.log

boot.log.2021-12-08.0.gz
boot.log.2021-12-08.1.gz
boot.log.2021-12-08.2.gz
boot.log.2021-12-08.3.gz

日誌會以 天(日期,如:2021-12-08)為單位進行歸檔壓縮(GZ 格式),考慮到該 天 內可能會有多個歸檔文件,歸檔壓縮文件名稱中會包含有序號(如:0、1、2、3)。

日誌輪替

我們也可以通過配置屬性自定義日誌輪替過程:

logging:
  file:
    name: /tmp/boot.log
  logback:
    rollingpolicy:
      file-name-pattern: /tmp/boot-%d{yyyy-MM-dd}.%i.log
      clean-history-on-start: false
      max-file-size: 1GB
      total-size-cap: 10GB
      max-history: 7

日誌輪替底層使用的是 Logback SizeAndTimeBasedRollingPolicy,同時支援按照 日誌時間日誌大小 進行歸檔。

  • logging.logback.rollingpolicy.file-name-pattern

    歸檔文件名稱模式,即:按照什麼樣的規則生成歸檔文件名稱,文件名稱中可以包含時間和序號。
    時間,表示按日誌時間歸檔,使用 %d{…} 用於指定具體的日期時間格式(Java SimpleDateFormat), yyyy-MM-dd 表示按天(日期)歸檔(按日誌時間歸檔);
    序號,表示同一個歸檔時間下,因日誌大小達到閾值,日誌歸檔多次產生多個歸檔文件的序號;

    boot.log
    boot-2021-12-08.0.log
    boot-2021-12-08.1.log
    boot-2021-12-08.2.log
    boot-2021-12-08.3.log
    ......
    
  • logging.logback.rollingpolicy.max-file-size

    日誌文件大小最大值,使用 KB/MB/GB/… 為單位進行指定;日誌文件大小超過設置的最大值,會進行日誌歸檔(按日誌大小歸檔)。

  • logging.logback.rollingpolicy.total-size-cap

    日誌文件(日誌文件 + 歸檔文件)總大小,使用 KB/MB/GB/… 為單位進行指定;日誌文件總大小超過設置的值,會刪除老(舊)的歸檔文件,直到日誌文件總大小小於設置的值。

  • logging.logback.rollingpolicy.max-history

    歸檔日誌文件保留天數,歸檔時間超出保留天數範圍的歸檔文件會被刪除。

  • logging.logback.rollingpolicy.clean-history-on-start

    歸檔文件的刪除是在日誌輸出過程中執行的,這個屬性可以指定應用啟動時是否執行一次歸檔文檔(因日誌時間或大小)的刪除,true 為執行,false 為不執行。

日誌級別

日誌記錄器(logger)是有層次結構的,我們可以為不同的層次的記錄器指定不同的日誌輸出級別。

指定根(root)記錄器日誌輸出級別:

logging:
  level:
    root: info

如前文所述,日誌記錄器的名稱通常是類名,我們可以認為日誌記錄器的層次結構是按照類名結構設計的:

父包名 + 若干子包名 + 類名

以 com.aopeila.meetu.boot.api.Main 為例,我們可以按照如下方式分別指定不同層次日誌記錄器的輸出級別:

logging:
  level:
    com: debug
    com.aopeila: info
    com.aopeila.meetu: warn
    com.aopeila.meetu.boot.api.Main: error

日誌記錄器會按 最長前綴匹配 計算日誌應使用的輸出級別,如果沒有匹配到,則使用根記錄器的日誌輸出級別。

日誌分組

我們可以把相關的一些日誌記錄器(logger)合併為一個分組(group),然後以分組為單位進行配置。

比如,可以把所有 Tomcat 相關的日誌記錄器合併為一個分組:

logging:
  group:
    tomcat: "org.apache.catalina,org.apache.coyote,org.apache.tomcat"

我們把以下日誌記錄器:

org.apache.catalina
org.apache.coyote
org.apache.tomcat

合併為一個分組 tomcat。

然後就可以使用分組 tomcat 進行日誌屬性的配置,如統一設置日誌級別:

logging:
  level:
    tomcat: "trace"

將分組 tomcat 日誌級別設置為 trace,也就是將前面提到的三個日誌記錄器的日誌級別設置為 trace。

小結

SpringBoot 默認集成 Logback 提供的日誌功能,應該可以滿足我們日常大部分需求場景,配置也比較簡單,推薦大家在實際項目中使用。