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