日誌記錄

Spring Boot 針對所有內部日誌記錄使用 Commons Logging,但將底層日誌實作保持開放。針對 Java Util LoggingLog4j2Logback 提供預設組態。在每種情況下,記錄器都預先組態為使用主控台輸出,並可選用檔案輸出。

預設情況下,如果您使用 starters,則 Logback 會用於日誌記錄。也包含適當的 Logback 路由,以確保使用 Java Util Logging、Commons Logging、Log4J 或 SLF4J 的依賴程式庫都能正確運作。

Java 有許多可用的日誌記錄框架。如果以上列表讓您感到困惑,請別擔心。通常,您不需要變更您的日誌記錄依賴,而且 Spring Boot 預設值運作良好。
當您將應用程式部署到 Servlet 容器或應用程式伺服器時,使用 Java Util Logging API 執行的日誌記錄不會路由到您應用程式的日誌中。這可以防止容器或已部署到容器的其他應用程式執行的日誌記錄出現在您應用程式的日誌中。

日誌格式

Spring Boot 的預設日誌輸出類似於以下範例

2024-10-24T12:02:42.179Z  INFO 112052 --- [myapp] [           main] o.s.b.d.f.logexample.MyApplication       : Starting MyApplication using Java 17.0.13 with PID 112052 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2024-10-24T12:02:42.211Z  INFO 112052 --- [myapp] [           main] o.s.b.d.f.logexample.MyApplication       : No active profile set, falling back to 1 default profile: "default"
2024-10-24T12:02:45.743Z  INFO 112052 --- [myapp] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2024-10-24T12:02:45.764Z  INFO 112052 --- [myapp] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-10-24T12:02:45.765Z  INFO 112052 --- [myapp] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.31]
2024-10-24T12:02:45.863Z  INFO 112052 --- [myapp] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-10-24T12:02:45.869Z  INFO 112052 --- [myapp] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3429 ms
2024-10-24T12:02:47.030Z  INFO 112052 --- [myapp] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
2024-10-24T12:02:47.049Z  INFO 112052 --- [myapp] [           main] o.s.b.d.f.logexample.MyApplication       : Started MyApplication in 6.238 seconds (process running for 7.345)

以下項目會輸出

  • 日期和時間:毫秒精確度且易於排序。

  • 日誌層級:ERRORWARNINFODEBUGTRACE

  • 程序 ID。

  • --- 分隔符號,用於區分實際日誌訊息的開始。

  • 應用程式名稱:以方括號括住(預設情況下僅在設定 spring.application.name 時記錄)

  • 執行緒名稱:以方括號括住(可能會為了主控台輸出而截斷)。

  • 關聯 ID:如果啟用追蹤(未顯示在以上範例中)

  • 記錄器名稱:這通常是來源類別名稱(通常會縮寫)。

  • 日誌訊息。

Logback 沒有 FATAL 層級。它會映射到 ERROR
如果您有 spring.application.name 屬性,但不想要記錄它,您可以將 logging.include-application-name 設定為 false

主控台輸出

預設日誌組態會將訊息回顯到主控台,因為它們是寫入的。預設情況下,會記錄 ERROR 層級、WARN 層級和 INFO 層級訊息。您也可以透過使用 --debug 旗標啟動應用程式來啟用「偵錯」模式。

$ java -jar myapp.jar --debug
您也可以在您的 application.properties 中指定 debug=true

當啟用偵錯模式時,會組態選取的核心記錄器(嵌入式容器、Hibernate 和 Spring Boot)以輸出更多資訊。啟用偵錯模式不會將您的應用程式組態為記錄所有具有 DEBUG 層級的訊息。

或者,您可以透過使用 --trace 旗標(或 application.properties 中的 trace=true)啟動應用程式來啟用「追蹤」模式。這樣做會為選取的核心記錄器(嵌入式容器、Hibernate 結構描述產生和整個 Spring 產品組合)啟用追蹤日誌記錄。

彩色編碼輸出

如果您的終端機支援 ANSI,則會使用彩色輸出以協助可讀性。您可以將 spring.output.ansi.enabled 設定為 支援的值 以覆寫自動偵測。

彩色編碼是透過使用 %clr 轉換字詞來組態的。在其最簡單的形式中,轉換器會根據日誌層級為輸出著色,如下列範例所示

%clr(%5p)

下表描述日誌層級到顏色的映射

層級 顏色

FATAL

紅色

ERROR

紅色

WARN

黃色

INFO

綠色

DEBUG

綠色

TRACE

綠色

或者,您可以透過將顏色或樣式作為轉換的選項來指定應使用的顏色或樣式。例如,若要使文字變成黃色,請使用以下設定

%clr(%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}){yellow}

支援以下顏色和樣式

  • 藍色

  • 青色

  • 微弱

  • 綠色

  • 洋紅色

  • 紅色

  • 黃色

檔案輸出

預設情況下,Spring Boot 僅記錄到主控台,並且不寫入日誌檔。如果您想要除了主控台輸出之外還寫入日誌檔,您需要設定 logging.file.namelogging.file.path 屬性(例如,在您的 application.properties 中)。如果同時設定了這兩個屬性,則會忽略 logging.file.path,並且僅使用 logging.file.name

下表顯示 logging.* 屬性如何一起使用

表 1. 日誌記錄屬性
logging.file.name logging.file.path 描述

(無)

(無)

僅主控台日誌記錄。

特定檔案(例如,my.log

(無)

寫入到 logging.file.name 指定的位置。位置可以是絕對路徑或相對於目前目錄。

(無)

特定目錄(例如,/var/log

spring.log 寫入到 logging.file.path 指定的目錄。目錄可以是絕對路徑或相對於目前目錄。

特定檔案

特定目錄

寫入到 logging.file.name 指定的位置,並忽略 logging.file.path。位置可以是絕對路徑或相對於目前目錄。

日誌檔在達到 10 MB 時會輪換,並且與主控台輸出一樣,預設情況下會記錄 ERROR 層級、WARN 層級和 INFO 層級訊息。

日誌記錄屬性與實際的日誌記錄基礎架構無關。因此,Spring Boot 不會管理特定的組態金鑰(例如 Logback 的 logback.configurationFile)。

檔案輪換

如果您使用的是 Logback,則可以使用您的 application.propertiesapplication.yaml 檔案來微調日誌輪換設定。對於所有其他日誌記錄系統,您將需要直接自行組態輪換設定(例如,如果您使用 Log4j2,則可以新增 log4j2.xmllog4j2-spring.xml 檔案)。

支援以下輪換策略屬性

名稱 描述

logging.logback.rollingpolicy.file-name-pattern

用於建立日誌歸檔的檔案名稱模式。

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

是否應在應用程式啟動時執行日誌歸檔清理。

logging.logback.rollingpolicy.max-file-size

日誌檔在歸檔之前的最大大小。

logging.logback.rollingpolicy.total-size-cap

日誌歸檔在刪除之前可以佔用的最大大小。

logging.logback.rollingpolicy.max-history

要保留的最大歸檔日誌檔數量(預設為 7)。

日誌層級

所有支援的日誌記錄系統都可以在 Spring Environment 中設定記錄器層級(例如,在 application.properties 中),方法是使用 logging.level.<logger-name>=<level>,其中 level 是 TRACE、DEBUG、INFO、WARN、ERROR、FATAL 或 OFF 之一。可以使用 logging.level.root 組態 root 記錄器。

以下範例顯示 application.properties 中的潛在日誌記錄設定

  • 屬性

  • YAML

logging.level.root=warn
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error
logging:
  level:
    root: "warn"
    org.springframework.web: "debug"
    org.hibernate: "error"

也可以使用環境變數設定日誌層級。例如,LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG 會將 org.springframework.web 設定為 DEBUG

以上方法僅適用於套件層級日誌記錄。由於寬鬆綁定 始終將環境變數轉換為小寫,因此無法以這種方式為個別類別組態日誌記錄。如果您需要為類別組態日誌記錄,則可以使用 SPRING_APPLICATION_JSON 變數。

日誌群組

能夠將相關記錄器分組在一起以便可以同時組態它們通常很有用。例如,您可能會經常變更所有 Tomcat 相關記錄器的日誌記錄層級,但您無法輕易記住頂層套件。

為了幫助您做到這一點,Spring Boot 允許您在 Spring Environment 中定義日誌群組。例如,以下是如何透過將「tomcat」群組新增到您的 application.properties 來定義它

  • 屬性

  • YAML

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

定義後,您可以使用單行程式碼變更群組中所有記錄器的層級

  • 屬性

  • YAML

logging.level.tomcat=trace
logging:
  level:
    tomcat: "trace"

Spring Boot 包含以下可直接使用的預先定義日誌群組

名稱 記錄器

web

org.springframework.core.codecorg.springframework.httporg.springframework.weborg.springframework.boot.actuate.endpoint.weborg.springframework.boot.web.servlet.ServletContextInitializerBeans

sql

org.springframework.jdbc.coreorg.hibernate.SQLorg.jooq.tools.LoggerListener

使用日誌關閉掛鉤

為了在應用程式終止時釋放日誌記錄資源,提供了一個關閉掛鉤,它會在 JVM 退出時觸發日誌系統清理。除非您的應用程式部署為 war 檔案,否則會自動註冊此關閉掛鉤。如果您的應用程式具有複雜的內容階層,則關閉掛鉤可能無法滿足您的需求。如果無法滿足您的需求,請停用關閉掛鉤並調查底層日誌記錄系統直接提供的選項。例如,Logback 提供 內容選擇器,允許在自己的內容中建立每個記錄器。您可以使用 logging.register-shutdown-hook 屬性停用關閉掛鉤。將其設定為 false 將停用註冊。您可以在您的 application.propertiesapplication.yaml 檔案中設定該屬性

  • 屬性

  • YAML

logging.register-shutdown-hook=false
logging:
  register-shutdown-hook: false

自訂日誌組態

可以透過在類別路徑上包含適當的程式庫來啟動各種日誌記錄系統,並且可以透過在類別路徑的根目錄或由以下 Spring Environment 屬性指定的位置中提供適當的組態檔來進一步自訂:logging.config

您可以透過使用 org.springframework.boot.logging.LoggingSystem 系統屬性,強制 Spring Boot 使用特定的日誌記錄系統。該值應該是 LoggingSystem 實作的完整類別名稱。您也可以透過使用值 none 完全停用 Spring Boot 的日誌記錄組態。

由於日誌記錄是在建立 ApplicationContext 之前初始化的,因此無法從 Spring @Configuration 檔案中的 @PropertySources 控制日誌記錄。變更日誌記錄系統或完全停用它的唯一方法是透過系統屬性。

根據您的日誌記錄系統,會載入以下檔案

日誌記錄系統 自訂

Logback

logback-spring.xmllogback-spring.groovylogback.xmllogback.groovy

Log4j2

log4j2-spring.xmllog4j2.xml

JDK (Java Util Logging)

logging.properties

如果可能,我們建議您針對您的日誌記錄組態使用 -spring 變體(例如,logback-spring.xml 而不是 logback.xml)。如果您使用標準組態位置,Spring 無法完全控制日誌初始化。
Java Util Logging 存在已知的類別載入問題,這會在從「可執行 jar」執行時造成問題。如果可能,我們建議您在從「可執行 jar」執行時避免使用它。

為了協助自訂,一些其他屬性會從 Spring Environment 傳輸到系統屬性。這允許日誌記錄系統組態使用這些屬性。例如,在 application.properties 中設定 logging.file.name 或將 LOGGING_FILE_NAME 設定為環境變數將導致設定 LOG_FILE 系統屬性。下表描述了傳輸的屬性

Spring Environment 系統屬性 註解

logging.exception-conversion-word

LOG_EXCEPTION_CONVERSION_WORD

記錄例外狀況時使用的轉換字詞。

logging.file.name

logging.file.name

LOG_FILE

logging.file.path

如果已定義,則會在預設日誌組態中使用它。

LOG_FILE

logging.file.path

LOG_PATH

logging.pattern.console

CONSOLE_LOG_PATTERN

要在主控台 (stdout) 上使用的日誌模式。

logging.pattern.dateformat

LOG_DATEFORMAT_PATTERN

日誌日期格式的 Appender 模式。

logging.charset.console

CONSOLE_LOG_CHARSET

用於主控台日誌記錄的字元集。

logging.threshold.console

CONSOLE_LOG_THRESHOLD

用於主控台日誌記錄的日誌層級閾值。

logging.pattern.file

FILE_LOG_PATTERN

要在檔案中使用的日誌模式(如果啟用 LOG_FILE)。

logging.charset.file

FILE_LOG_CHARSET

用於檔案日誌記錄的字元集(如果啟用 LOG_FILE)。

logging.threshold.file

FILE_LOG_THRESHOLD

用於檔案日誌記錄的日誌層級閾值。

logging.pattern.level

LOG_LEVEL_PATTERN

LOG_LEVEL_PATTERN

用於轉譯日誌層級的格式(預設為 %5p)。

PID

Spring Environment 系統屬性 註解

logging.logback.rollingpolicy.file-name-pattern

目前的程序 ID(如果可能且在尚未定義為 OS 環境變數時探索到)。

如果您使用 Logback,也會傳輸以下屬性

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

logging.logback.rollingpolicy.file-name-pattern

LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN

logging.logback.rollingpolicy.max-file-size

輪換日誌檔名稱的模式(預設為 ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz)。

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

logging.logback.rollingpolicy.total-size-cap

LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START

是否在啟動時清理歸檔日誌檔。

logging.logback.rollingpolicy.max-history

logging.logback.rollingpolicy.max-file-size

LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE

最大日誌檔大小。

要保留的日誌備份總大小。

logging.logback.rollingpolicy.max-history

2019-08-30 12:30:04.031 user:someone INFO 22174 --- [  nio-8080-exec-0] demo.Controller
Handling authenticated request

LOGBACK_ROLLINGPOLICY_MAX_HISTORY

要保留的最大歸檔日誌檔數量。

所有支援的日誌記錄系統都可以在剖析其組態檔時查詢系統屬性。請參閱 spring-boot.jar 中的預設組態以取得範例
Log4j 2
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]

Java Util logging

如果您想要在日誌記錄屬性中使用預留位置,則應使用 Spring Boot 的語法,而不是底層框架的語法。值得注意的是,如果您使用 Logback,則應使用 : 作為屬性名稱及其預設值之間的分隔符號,而不是使用 :-

<springProfile name="staging">
	<!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev | staging">
	<!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
	<!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

您可以僅覆寫 LOG_LEVEL_PATTERN(或 Logback 的 logging.pattern.level)來將 MDC 和其他特設內容新增到日誌行。例如,如果您使用 logging.pattern.level=user:%X{user} %5p,則預設日誌格式會包含「user」的 MDC 項目(如果存在),如下列範例所示。

Logback 擴充功能

<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
		defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
	<remoteHost>${fluentHost}</remoteHost>
	...
</appender>
Spring Boot 包含許多 Logback 的擴充功能,可以協助進行進階組態。您可以在您的 logback-spring.xml 組態檔中使用這些擴充功能。

由於標準 logback.xml 組態檔載入得太早,因此您無法在其中使用擴充功能。您需要使用 logback-spring.xml 或定義 logging.config 屬性。

這些擴充功能無法與 Logback 的 組態掃描 一起使用。如果您嘗試這樣做,則對組態檔所做的變更會導致記錄類似於以下其中一項的錯誤

特定 Profile 組態
<springProfile> 標籤可讓您根據作用中的 Spring Profile,選擇性地包含或排除組態的區段。Profile 區段在 <configuration> 元素內的任何位置都受到支援。使用 name 屬性指定哪個 Profile 接受組態。<springProfile> 標籤可以包含 Profile 名稱(例如 staging)或 Profile 運算式。Profile 運算式允許表示更複雜的 Profile 邏輯,例如 production & (eu-central | eu-west)。請查看 Spring Framework 參考指南 以取得更多詳細資訊。以下清單顯示三個範例 Profile

環境屬性

<springProperty> 標籤可讓您公開 Spring Environment 中的屬性,以在 Logback 中使用。如果您想要在 Logback 組態中存取來自 application.properties 檔案的值,這樣做可能會很有用。該標籤的運作方式與 Logback 的標準 <property> 標籤類似。但是,您不是指定直接 value,而是指定屬性的 source(來自 Environment)。如果您需要將屬性儲存在本機範圍以外的其他位置,則可以使用 scope 屬性。如果您需要回退值(以防 Environment 中未設定屬性),則可以使用 defaultValue 屬性。以下範例顯示如何公開屬性以在 Logback 中使用

<SpringProfile name="staging">
	<!-- configuration to be enabled when the "staging" profile is active -->
</SpringProfile>

<SpringProfile name="dev | staging">
	<!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</SpringProfile>

<SpringProfile name="!production">
	<!-- configuration to be enabled when the "production" profile is not active -->
</SpringProfile>

source 必須以 kebab case 指定(例如 my.property-name)。但是,可以使用寬鬆規則將屬性新增到 Environment

Log4j2 擴充功能

Spring Boot 包含許多 Log4j2 的擴充功能,可以協助進行進階組態。您可以在任何 log4j2-spring.xml 組態檔中使用這些擴充功能。

<Properties>
	<Property name="applicationName">${spring:spring.application.name}</Property>
</Properties>
由於標準 log4j2.xml 組態檔載入得太早,因此您無法在其中使用擴充功能。您需要使用 log4j2-spring.xml 或定義 logging.config 屬性。

這些擴充功能取代了 Log4J 提供的 Spring Boot 支援。您應確保不要在您的建置中包含 org.apache.logging.log4j:log4j-spring-boot 模組。

特定 Profile 組態

<SpringProfile> 標籤可讓您根據作用中的 Spring Profile,選擇性地包含或排除組態的區段。Profile 區段在 <Configuration> 元素內的任何位置都受到支援。使用 name 屬性指定哪個 Profile 接受組態。<SpringProfile> 標籤可以包含 Profile 名稱(例如 staging)或 Profile 運算式。Profile 運算式允許表示更複雜的 Profile 邏輯,例如 production & (eu-central | eu-west)。請查看 Spring Framework 參考指南 以取得更多詳細資訊。以下清單顯示三個範例 Profile

環境屬性查詢
如果您想要在 Log4j2 組態中參考來自 Spring Environment 的屬性,則可以使用 spring: 前綴的 查詢。如果您想要在 Log4j2 組態中存取來自 application.properties 檔案的值,這樣做可能會很有用。