1. 程式人生 > 實用技巧 >Spring Boot2(013):日誌

Spring Boot2(013):日誌

Spring Boot2系列文章可以通過這裡進行回顧:SpringBoot2(001):入門介紹、官網參考和部落格彙總


  本文主要針對 SpringBoot 應用的日誌記錄進行介紹,包括如何定製日誌格式、日誌檔案、日誌配置、選用哪些日誌框架實現等,主要參考官方文件:26. Logging ,目錄結構如下:

  SpringBoot 使用 Commons Logging 作為內建的日誌實現,但保留了低層的日誌實現。 Java Util Logging, Log4J2, 和 Logback 都提供了預設配置。在每種情況下,日誌記錄器都預先配置為使用控制檯作為輸出,和可選的日誌檔案輸出。

  如果使用了 Starters ,預設情況下會使用 Logback 進行日誌記錄。恰當的 Logback 路由也會被包含進來,以確保使用 Java Util Logging, Commons Logging, Log4J, 或 SLF4J 的依賴包都能正常工作。

注:Java 有很多可用的 logging 框架。開發者並不需要對著上述的日誌框架列表感到困惑。總體上來說,開發者並不需要修改日誌依賴,SpringBoot 的預設配置會處理得很好。

1、日誌格式 Log Format

  預設的日誌輸出就像下面這個樣子:

2014-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms 2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]

  輸出內容項如下:

  • 日期和時間:精確到毫秒,便於分類
  • 日誌級別:ERROR, WARN, INFO, DEBUG, 或者 TRACE
  • 處理ID(Process ID)
  • --- 分隔符,區分實際日誌的開始。
  • 執行緒名稱:[] 包起來(可能被控制檯輸出截斷)
  • Logger名稱:通常是列印日誌的源類名稱(通常是縮寫限定名)
  • 日誌資訊

  Logback 並沒有 FATAL 級別的日誌,對應的是 ERROR 。

2、控制檯輸出 Console Output

  預設日誌配置在寫入訊息時將訊息回顯到控制檯,預設輸出 ERROR, WARN, 和 INFO 級別的日誌訊息。開發者可以通過在啟動應用時增加 --flag(flag 表示日誌級別,例如 --debug ) 引數來開啟 debug 模式。

$ java -jar myapp.jar --debug

注:也可以通過在 application.properties 中配置 debug=true 來開啟 debug 級別。

  當啟用 debug 模式時,一組核心 loggers (嵌入式容器、Hibernate, 和 Spring Boot)將會被配置以輸出更多資訊。開啟 debug 模式並不意味著會配置應用的所有日誌訊息輸出為 DEBUG 級別。

  另外,開發者還可以通過 --trace 標誌(或者在 application.properties 配置 trace=true)來開啟 trace 模式。這樣做會為一系列核心 loggers(嵌入式容器,Hibernate 模式生成,和整個 Spring 組合)開啟 trace 日誌記錄。

2.1、彩色編碼輸出

  如果開發者的終端支援 ANSI,彩色輸出可以用來幫助提升可讀性。開發者可以設定 spring.output.ansi.enabled 到一個 支援的值 以便支援預設的自動檢測。彩色編碼通過使用 %clr 轉換字進行配置。最簡單的形式是,轉換器根據日誌級別為輸出著色,如下:

%clr(%5p)

  下表描述了日誌級別及對應的彩色對映關係:

Level Color
FATAL Red
ERROR Red
WARN Yellow
INFO Green
DEBUG Green
TRACE Green

  或者,開發者可以通過提供應該要使用的顏色或樣式作為轉換的選項。例如,為了使文字輸出為黃色,使用如下的設定:

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

  如下顏色和樣式都是支援的:

  • blue
  • cyan
  • faint
  • green
  • magenta
  • red
  • yellow

3、檔案輸出

  預設情況下,SpringBoot 只會記錄日誌到控制檯,並不會寫到日誌檔案去。開發者如果除了控制檯輸出之外還想寫入日誌檔案,需要設定 logging.file 或者 logging.path 屬性(例如在 application.properties 中)。

  如下示例展示了 logging.* 可以怎樣被一起使用:

logging.file logging.path Example Description
(none) (none) Console only logging.
Specific file (none) my.log Writes to the specified log file. Names can be an exact location or relative to the current directory.
(none) Specific directory /var/log Writes spring.log to the specified directory. Names can be an exact location or relative to the current directory.

  日誌檔案到達 10MB 時會滾動生成新的,並且日誌檔案也像控制檯輸出一樣,預設情況下會記錄 ERROR, WARN, 和 INFO 級別的日誌。檔案大小限制可以通過 logging.file.max-size 屬性進行修改。先前的日誌檔案會被永久歸檔儲存,除非指定了 logging.file.max-history 進行限制。

注:日誌系統會在應用生命週期的早期進行初始化。因此,在通過 @PropertySource 註解載入的屬性檔案中會找不到日誌屬性。

注:日誌屬性獨立於實際的日誌基礎框架。因此,特定的配置鍵(例如 Logback 中的 logback.configurationFile )並不會被 SpringBoot 進行管理。

4、日誌級別

  所有支援的日誌系統都可以在 Spring 的 Environment 中通過使用 logging.level.<logger-name>=<level> 來設定日誌級別,其中 level 可以是 TRACE, DEBUG, INFO, WARN, ERROR, FATAL, 或者 OFF 中的任意一個。root logger 可以通過 logging.level.root 進行設定。

  下面的例子展示了 application.properties 中潛在的日誌設定:

  • logging.level.root=WARN
  • logging.level.org.springframework.web=DEBUG
  • logging.level.org.hibernate=ERROR

5、日誌分組

  能夠將相關的日誌記錄器分組在一起,這樣就可以同時對它們進行配置,這通常很有用。例如,開發者通常可能會更改所有 Tomcat 相關的日誌記錄器的日誌級別,但是記住 tomcat 的頂級包通常不容易。

  為了處理這種情況,SpringBoot 允許在 Spring Environment 中定義日誌分組。如下就是在 application.properties 中添加了一個 tomcat 分組:

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

  一旦定義好了,開發者就可以通過一行配置來修改分組裡面的所有日誌記錄器的日誌級別

logging.level.tomcat=TRACE

  SpringBoot 包含了如下預定義的日誌分組,可以開箱即用:

Name Loggers
web org.springframework.core.codec, org.springframework.http, org.springframework.web
sql org.springframework.jdbc.core, org.hibernate.SQL

6、定製日誌配置

  可以通過在 classpath 包含不同的引用包來啟用不同的日誌系統,還可以通過在 根 classpath 或者 Spring Environment 的屬性 logging.config 指定的路徑中提供合適的配置檔案來進一步定製日誌配置。

  開發者可以通過系統屬性 org.springframework.boot.logging.LoggingSystem 來強制指定使用特定的日誌系統。這個屬性值應該使用日誌系統實現類的全限定名。開發者可以將值設定為 none 來完全關閉 SpringBoot 的日誌配置。

注:由於日誌會在 ApplicationContext 建立前進行初始化,不可能通過 Spring 的 @Configuration 檔案中的 @PropertySources 來控制日誌配置。

  取決於日誌系統,以下配置檔案將會被載入:

Logging System Customization
Logback logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging) logging.properties

注:可以的話,建議開發者使用 -spring 字尾的日誌配置(例如使用 logback-spring.xml 而不是 logback.xml )。如果使用標準配置路徑,Spring 不能完全控制日誌初始化。

注:從 'executable jar' 執行時,Java Util Logging 有一些已知的會導致問題的 classloading issues 。建議開發者從 'executable jar' 執行時儘可能避免它。

  為了方便定製日誌,其他一些屬性會從 Spring Environment 轉移到系統屬性 System properties,如下表描述:

Spring Environment System Property Comments
logging.exception-conversion-word LOG_EXCEPTION_CONVERSION_WORD The conversion word used when logging exceptions.
logging.file LOG_FILE If defined, it is used in the default log configuration.
logging.file.max-size LOG_FILE_MAX_SIZE Maximum log file size (if LOG_FILE enabled). (Only supported with the default Logback setup.)
logging.file.max-history LOG_FILE_MAX_HISTORY Maximum number of archive log files to keep (if LOG_FILE enabled). (Only supported with the default Logback setup.)
logging.path LOG_PATH If defined, it is used in the default log configuration.
logging.pattern.console CONSOLE_LOG_PATTERN The log pattern to use on the console (stdout). (Only supported with the default Logback setup.)
logging.pattern.dateformat LOG_DATEFORMAT_PATTERN Appender pattern for log date format. (Only supported with the default Logback setup.)
logging.pattern.file FILE_LOG_PATTERN The log pattern to use in a file (if LOG_FILE is enabled). (Only supported with the default Logback setup.)
logging.pattern.level LOG_LEVEL_PATTERN The format to use when rendering the log level (default %5p). (Only supported with the default Logback setup.)
PID PID The current process ID (discovered if possible and when not already defined as an OS environment variable).

所有支援的日誌系統在解析配置檔案的時候都可以訪問系統屬性。具體參考 spring-boot.jar 中的預設配置:

建議:如果希望在日誌屬性中使用佔位符,應該使用 Spring Boot的語法,而不是底層框架的語法。值得注意的是,如果開發者使用了 Logback ,應該使用 : 作為屬性名和預設值的分隔符,而不是 :- 。

建議:僅通過覆蓋 LOG_LEVEL_PATTERN (或 Logback 的 logging.pattern.level ),開發者可以將 MDC 和其他特別內容新增到日誌記錄行中。例如,使用 logging.pattern.level=user:%X{user} %5p ,則預設的日誌記錄格式中會包含有 "user" 的 MDC 條目(如果存在的話),如下所示:

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

7、Logback 擴充套件

  Spring Boot 提供了一系列 Logback 擴充套件用於進行高階配置。開發者可以在 logback-spring.xml 配置檔案中使用這些擴充套件。

注:因為標準的 logback.xml 會過早載入,所以用不了擴充套件。開發者需要確保使用的是 logback-spring.xml 或者 定義了 logging.config 屬性。

警告: Logback 擴充套件不能和 Logback’s configuration scanning 一起使用。如果開發者這樣做,修改日誌配置檔案可能會導致類似如下記錄的錯誤:

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]]

7.1、Profile-specific Configuration

  <springProfile> 標籤允許開發者根據啟用的 Spring profiles 來選擇包含或排除部分配置。配置部分被包含在 <configuration> 元素中。使用 name 屬性來指定哪個 profile 需要使用哪些配置。<springProfile> 標籤允許使用簡單的 profile name (例如 staging),也支援 profile 表示式。profile expression 允許更加複雜的表示邏輯,例如 production & (eu-central | eu-west) 。詳情參考: reference guide 。下述列表描述了3種樣例:

<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>

7.2 環境屬性 Environment Properties

  <springProperty> 標籤允許從 Spring Environment 公開屬性給 Logback 使用。如果開發者想要在 Logback 配置中訪問 application.properties 檔案中的屬性值的話,這樣做確實會很有用。這個標籤和 Logback 的標準標籤 <property> 工作方式類似。然而,開發者指定屬性來源(從 Environment ),而不是直接指定值。如果開發者需要將改屬性值儲存在除本地範圍之外的其他地方,則可以使用 scope 屬性。如果需要指定 a fallback value(在 Environment 中沒有設定該屬性的情況下使用),可以使用 defaultValue 屬性。下面這個例子展示瞭如何公開屬性以便供 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>

注:source 必須使用橫杆的方式進行指定(例如: my.property-name )。然而,新增到 Environment 中的屬性是可以使用寬鬆的規則繫結。

8、參考