Spring Boot日志詳解


Spring Boot中的日志抽象確實(shí)是SLF4J(Simple Logging Facade for Java)
,它是一個面向Java的簡單日志門面,旨在將各種現(xiàn)有的日志框架映射到基于統(tǒng)一抽象接口的通用API上。
通過使用SLF4J
,應(yīng)用程序可以將日志記錄器與任何后端日志實(shí)現(xiàn)(如Log4j、Logback、Java Util Logging等)進(jìn)行解耦。這使得在不更改應(yīng)用程序代碼的情況下,可以輕松地在不同的日志實(shí)現(xiàn)之間切換。
而Spring Boot中默認(rèn)的日志實(shí)現(xiàn)是Logback
當(dāng)然,你也可以在Spring Boot中使用各種不同的日志框架,比如Log4j2、SLF4j等,只需要在項(xiàng)目中引入對應(yīng)的依賴,按照對應(yīng)的配置方式即可。

簡化的日志調(diào)用關(guān)系圖

在 application.properties 文件中,logging.config 屬性用于指定 Logback 配置文件的位置。Logback 是一個流行的 Java 日志框架,它提供了一種靈活的方式來記錄應(yīng)用程序日志。logging.config=classpath:logback-spring.xml這將告訴 Spring Boot 使用 logback-spring.xml 文件作為 Logback 配置文件。請注意,classpath: 前綴表示該文件位于應(yīng)用程序的類路徑下。如果您沒有在 application.properties 文件中設(shè)置 logging.config 屬性,則 Spring Boot 將使用默認(rèn)的 Logback 配置。默認(rèn)情況下,Spring Boot 會在類路徑下查找名為 logback-spring.xml 或 logback.xml 的文件,并使用找到的第一個文件作為 Logback 配置文件。如果找不到任何文件,則 Spring Boot 將使用 Logback 的默認(rèn)配置。通過使用 logging.config 屬性,您可以輕松地指定 Logback 配置文件的位置,并自定義應(yīng)用程序的日志記錄行為。在 Spring Boot 中,默認(rèn)情況下,將使用 Logback 的默認(rèn)配置。Logback 是一個流行的 Java 日志框架,它提供了一種靈活的方式來記錄應(yīng)用程序日志。如果您沒有在應(yīng)用程序中顯式地配置 Logback,則 Spring Boot 將使用 Logback 的默認(rèn)配置。默認(rèn)情況下,Logback 的默認(rèn)配置將日志事件輸出到控制臺,并將日志級別設(shè)置為 INFO。如果您需要更改日志記錄行為,則可以在應(yīng)用程序中配置 Logback,例如通過創(chuàng)建一個名為 logback-spring.xml 的配置文件,并在其中定義附加器、日志記錄器和日志級別等元素。請注意,如果您使用的是 Spring Boot,那么 <shutdownHook> 通常不需要顯式添加,因?yàn)?Spring Boot 會自動注冊一個關(guān)閉鉤子來處理日志記錄。但是,在某些情況下,您可能需要手動添加 <shutdownHook> 以確保日志記錄在應(yīng)用程序關(guān)閉時能夠正常完成。
在Spring Boot中,默認(rèn)情況下會嘗試從以下幾個位置加載日志配置:
classpath:logback-spring.xml
classpath:logback-spring.groovy
classpath:logback.xml
classpath:logback.groovy
因此,當(dāng)您沒有在application.properties或application.yml中配置logging.config
屬性時,Spring Boot會按照默認(rèn)規(guī)則去加載上述配置文件。當(dāng)然,如果您需要加載的日志配置文件不在默認(rèn)路徑下,或者除了Logback以外的其他日志實(shí)現(xiàn),那么就需要在logging.config
屬性中顯式地指定日志配置文件路徑。
需要注意的是,當(dāng)存在多個日志配置文件時,Spring Boot會優(yōu)先加載后綴為-spring
的配置文件,這是因?yàn)?/span>Spring-boot-starter-logging
依賴中封裝了對于Spring的配置的特殊處理,使用該后綴的配置文件可以實(shí)現(xiàn)更強(qiáng)的靈活性和擴(kuò)展性,例如可以引入Spring的屬性占位符。
當(dāng)在application.properties/application.yml和logback-spring.xml中都配置了同一屬性時(比如logging.level.root
),Spring Boot會優(yōu)先讀取application.properties/application.yml中的配置,而忽略logback-spring.xml中的配置。
這是因?yàn)樵赟pring Boot的日志系統(tǒng)中,logging
屬性優(yōu)先級最高,即使你在 logback-spring.xml
中配置了某個屬性,如果在 application.properties/application.yml
中發(fā)現(xiàn)了同名的屬性,則會覆蓋logback-spring.xml
中的配置。這也是Spring Boot日志配置中logging
屬性優(yōu)先級高于logback-spring.xml中的原因。
因此,在實(shí)際應(yīng)用中,如果您需要對日志輸出級別、使用附加器等進(jìn)行配置,推薦使用logback-spring.xml這樣的日志配置文件,它可以實(shí)現(xiàn)更加靈活和細(xì)粒度的配置,而application.properties/application.yml中的配置主要用于簡潔明了的全局配置。
示例:
[,,,]
這一部分表示MDC(Mapped Diagnostic Context),它是一種記錄應(yīng)用程序信息的機(jī)制,在Logback框架和Spring Cloud Sleuth中都有應(yīng)用。
MDC機(jī)制通常用于在系統(tǒng)運(yùn)行時,記錄一些信息,在日志輸出時將這些信息一并輸出,幫助我們在分析日志時能夠更輕松地定位問題。例如,可以記錄請求ID、用戶IP、客戶端信息等,然后在日志中輸出這些信息,方便跟蹤和排查。
在Spring Cloud Sleuth中,MDC中一般會包含Trace ID、Span ID,代表當(dāng)前所在的請求鏈路信息,用于服務(wù)追蹤和調(diào)用鏈路追蹤。[,,,]
這種空的中括號表示當(dāng)前日志所在的上下文中沒有設(shè)置MDC信息。
需要注意的是,MDC中記錄的信息必須是線程私有的,不同線程之間不能共用MDC。若要在多線程環(huán)境下使用MDC,一般會配合使用ThreadLocal等線程安全的工具。
Logback支持自定義MDC信息??梢酝ㄟ^在代碼中設(shè)置MDC,然后在日志輸出時通過%X
占位符輸出MDC中的數(shù)據(jù)。比如:
在上面的代碼中,我們在MDC中添加了一個名為requestId
的鍵值對,然后在日志記錄時使用了%X
占位符將requestId
的值輸出。
在Logback的配置文件中也可以指定每個appender是否包含MDC信息,舉個例子:
在上面的配置中,我們使用了%X{requestId}
來輸出MDC中名為requestId
的鍵的值,將值輸出到日志消息的括號中。
需要注意的是,在Logback中設(shè)置MDC信息可能會對性能造成影響,過多或過大的MDC數(shù)據(jù)可能會導(dǎo)致GC times過長等問題。為了避免這些問題,應(yīng)該盡量精簡MDC信息,只記錄必要的信息。并且,MDC信息應(yīng)該在不使用時及時清除。
在Spring Cloud Sleuth中,MDC默認(rèn)記錄Trace ID、Span ID以及Parent Span ID三個值,它們在MDC中用逗號分隔,因此一般情況下,MDC值為3個逗號。
這三個值的具體含義如下:
Trace ID:標(biāo)識整個請求鏈路的ID,它能夠串聯(lián)整個請求鏈路中的所有Span。
Span ID:標(biāo)識當(dāng)前Span的ID,以區(qū)分一個Trace中包含的不同Span。
Parent Span ID:與Span ID一起使用,標(biāo)識當(dāng)前Span的父級Span ID。
這三個值在Spring Cloud Sleuth中都是使用UUID生成的唯一標(biāo)識符。在日志輸出時,可以使用%X{traceId}
、%X{spanId}
、%X{parentId}
這些占位符輸出這些值。
如果你在輸出日志時,發(fā)現(xiàn)MDC值不是三個逗號,而是其他的分隔符,或者對應(yīng)的值不是UUID,這可能是因?yàn)樽约盒薷牧伺渲脤?dǎo)致的,可以查看一下配置文件和相關(guān)代碼來進(jìn)行排查。
這個日志格式中的 true
表示是否已經(jīng)記錄了正確的MDC值,即Trace ID、Span ID以及Parent Span ID三個值。當(dāng)為true時,表示MDC中已記錄了這三個值,并且這些值可以跨度傳播至請求鏈中的下游調(diào)用。如果值為false,則可能意味著MDC沒有設(shè)置好,或者日志記錄器沒有正確的配置。
