SpringBoot整合日志功能(slf4j+logback)詳解(最新推薦)
一、日志門面與日志實現(xiàn)
1.1 什么是日志門面和日志實現(xiàn)?
日志門面相當于JDBC接口,而日志實現(xiàn)類似于Mysql、Oracle、SqlServer等。
在Java生態(tài)體系中,圍繞著日志,有很多成熟的解決方案。關(guān)于日志輸出,主要有兩類工具。
一類是日志框架(Log4j、Logback),主要用來進行日志的輸出的,比如輸出到哪個文件,日志格式如何等。另 外一類是日志門面(slf4j,commons-logging),主要一套通用的API,用來屏蔽各個日志框架之間的差異的。
對于Java工程師來說,關(guān)于日志工具的使用,最佳實踐就是在應用中使用如Log4j + SLF4J這樣的組合來進行日志 輸出。
這樣做的最大好處,就是業(yè)務層的開發(fā)不需要關(guān)心底層日志框架的實現(xiàn)及細節(jié),在編碼的時候也不需要考慮日后更 換框架所帶來的成本。這也是門面模式所帶來的好處。
1.2 為什么需要日志門面?
前面提到過一個重要的原因,就是為了在應用中屏蔽掉底層日志框架的具體實現(xiàn)。這樣的話,即使有一天要更換代 碼的日志框架,只需要修改jar包,最多再改改日志輸出相關(guān)的配置文件就可以了。這就是解除了應用和日志框架 之間的耦合。
有人或許會問了,如果我換了日志框架了,應用是不是就改了,那日志門面不還是需要改的嗎?
要回答這個問題,我們先來舉一個例子,再把門面模式碎了重新解釋一遍。
日志門面就像飯店的服務員,而日志框架就像是后廚的廚師。對于顧客這個應用來說,我到飯店點菜,我只需要告 訴服務員我要一盤番茄炒雞蛋即可,我不關(guān)心他后廚的所有事情。因為雖然主廚從把這道菜稱之為「番茄炒蛋」的廚師 換成了把這道菜稱之為「西紅柿炒雞蛋」的廚師。但是,顧客不需要關(guān)心,他只要下達「番茄炒蛋」的命令給到 服務員,由服務員再去翻譯給廚師就可以了。
所以,對于一個了解了「番茄炒蛋」的多種叫法的服務員來說,無論后廚如何換廚師,他都能準確的幫用戶下單。
同理,對于一個設(shè)計的全面、完善的日志門面來說,他也應該是無縫兼容了多種日志框架的。所以,底層框架的 更換,日志門面幾乎不需要改動。
以上,就是日志門面的一個比較重要的好處——解耦。
二、簡介
- Spring使用commons-logging作為內(nèi)部日志,但底層日志實現(xiàn)是開放的。可對接其他日志框架。spring5及以后 commons-logging被spring直接自己寫了。
- 支持 jul,log4j2,logback。SpringBoot 提供了默認的控制臺輸出配置,也可以配置輸出為文件。
- logback是默認使用的。
- 雖然日志框架很多,但是我們不用擔心,使用 SpringBoot 的默認配置就能工作的很好。
SpringBoot怎么把日志默認配置好的?
- 每個
starter
場景,都會導入一個核心場景spring-boot-starter
- 核心場景引入了日志的所用功能
spring-boot-starter-logging
- 默認使用了
slf4j + logback
組合作為默認底層日志 日志是系統(tǒng)一啟動就要用
,而xxxAutoConfiguration
是系統(tǒng)啟動好了以后放好的組件,后來用的。- 日志是利用監(jiān)聽器機制配置好的。
ApplicationListener
。 - 日志所有的配置都可以通過修改配置文件實現(xiàn)。以
logging
開始的所有配置。
三、日志格式
2023-03-31T13:56:17.511+08:00 INFO 4944 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-03-31T13:56:17.511+08:00 INFO 4944 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.7]
默認輸出格式:
- 時間和日期:毫秒級精度
- 日志級別:ERROR, WARN, INFO, DEBUG, or TRACE.
- 進程 ID
- ---: 消息分割符
- 線程名: 使用[]包含
- Logger 名: 通常是產(chǎn)生日志的類名
- 消息: 日志記錄的內(nèi)容
注意: logback 沒有FATAL級別,對應的是ERROR
默認值:參照:spring-boot
包additional-spring-configuration-metadata.json
文件
默認輸出格式值:%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
在application.properties可修改為:
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} ===> %msg%n
啟動項目發(fā)現(xiàn)日志變成我們修改的樣子了。
四、記錄日志
4.1 使用日志工廠
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { Logger log = LoggerFactory.getLogger(getClass()); @GetMapping("/hello") public String hello(){ log.info("方法進來了..."); return "Hello,Spring Boot 3!"; } }
4.2 使用Lombok的@Slf4j注解
import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @Slf4j @RestController public class HelloController { @GetMapping("/hello") public String hello(){ log.info("方法進來了..."); return "Hello,Spring Boot 3!"; } }
五、日志級別
5.1 日志級別介紹
- 由低到高:ALL,TRACE, DEBUG, INFO, WARN, ERROR,FATAL,OFF;
- 只會打印指定級別及以上級別的日志
- ALL:打印所有日志
- TRACE:追蹤框架詳細流程日志,一般不使用
- DEBUG:開發(fā)調(diào)試細節(jié)日志
- INFO:關(guān)鍵、感興趣信息日志
- WARN:警告但不是錯誤的信息日志,比如:版本過時
- ERROR:業(yè)務錯誤日志,比如出現(xiàn)各種異常
- FATAL:致命錯誤日志,比如jvm系統(tǒng)崩潰
- OFF:關(guān)閉所有日志記錄
- 不指定級別的所有類,都使用root指定的級別作為默認級別
- SpringBoot日志默認級別是 INFO
也就是說,如果你配置文件沒有配置日志級別,那么默認級別是info,打印的也是info順序后面的日志級別,包括info、warn、error、fatal、off等。
5.2 配置日志級別
application.properties中配置:
logging.level.root = debug
這樣配置代表以后debug及以后級別的日志都可以打印。
5.3 指定某個包下的類使用某個級別
logging.level.com.atguigu.controller=debug
代表只有com.atguigu.controller包使用debug級別,其余都使用默認info級別。
5.4 占位符打印
import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @Slf4j @RestController public class HelloController { @GetMapping("/hello") public String hello(String a, String b){ log.info("info日志:參數(shù)a:{} 參數(shù)b:{}", a, b); return "Hello,Spring Boot 3!"; } }
六、日志分組
有這么一種場景,比如我的包很多,這些包都想設(shè)置debug級別,那么配置如下:
logging.level.com.atguigu.controller=debug
logging.level.com.atguigu.service=debug
logging.level.com.atguigu.dao=debug
logging.level.com.atguigu.entity=debug
logging.level.com.atguigu.common=debug
...
這樣當包有很多的時候,寫起來很麻煩?。?!那么有什么辦法呢?沒錯,就是分組。
比如我把這些包分成一個組,組名叫abc,配置如下:
logging.group.abc=com.atguigu.controller,com.atguigu.service,com.atguigu.dao,com.atguigu.entity,com.atguigu.common
logging.level.abc=debug
這樣不就簡便很多了嗎?
七、文件輸出
SpringBoot 默認只把日志寫在控制臺,如果想額外記錄到文件,可以在application.properties中添加logging.file.name or logging.file.path配置項。
logging.file.name | logging.file.path | 示例 | 效果 |
未指定 | 未指定 | 僅控制臺輸出 | |
指定 | 未指定 | my.log | 寫入指定文件??梢约勇窂?/p> |
未指定 | 指定 | /var/log | 寫入指定目錄,文件名為spring.log |
指定 | 指定 | 以logging.file.name為準 |
例:將日志打印在D盤的/logs/my.log中
logging.file.name=D:/logs/my.log
八、文件歸檔與滾動切割
比如我們將項目的日志打印到D:\\my.log中,那么時間短還行,如果持續(xù)一年,我們的日志文件將會非常大,打開都會崩的狀態(tài)。
歸檔:每天的日志單獨存到一個文檔中。
切割:每個文件10MB,超過大小切割成另外一個文件。
- 每天的日志應該獨立分割出來存檔。如果使用logback(SpringBoot 默認整合),可以通過application.properties/yaml文件指定日志滾動規(guī)則。
- 如果是其他日志系統(tǒng),需要自行配置(添加log4j2.xml或log4j2-spring.xml)
- 支持的滾動規(guī)則設(shè)置如下
配置項 | 描述 |
logging.logback.rollingpolicy.file-name-pattern | 日志存檔的文件名格式(默認值:${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz) |
logging.logback.rollingpolicy.clean-history-on-start | 應用啟動時是否清除以前存檔(默認值:false) |
logging.logback.rollingpolicy.max-file-size | 存檔前,每個日志文件的最大大?。J值:10MB) |
logging.logback.rollingpolicy.total-size-cap | 日志文件被刪除之前,可以容納的最大大小(默認值:0B)。設(shè)置1GB則磁盤存儲超過 1GB 日志后就會刪除舊日志文件 |
logging.logback.rollingpolicy.max-history | 日志文件保存的最大天數(shù)(默認值:7). |
例:
logging.file.name=D:\logs\my.log # LOG_FILE:代表我們配置的日志文件名,如my.log # yyyy-MM-dd:年月日 # %i:代表當天第幾個文件 logging.logback.rollingpolicy.file-name-pattern=${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz # 只要my.log日志文件大于10MB就會觸發(fā)日志歸檔,將當前日志文件壓縮為my.log.2019-01-01.1.gz logging.logback.rollingpolicy.max-file-size=10MB
九、自定義配置
通常我們配置 application.properties 就夠了。當然也可以自定義。比如:
日志系統(tǒng) | 自定義 |
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 無法完全控制日志初始化。
最佳實戰(zhàn):自己要寫配置,配置文件名加上 xx-spring.xml
十、切換日志組合
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
哪怕你切換log4j2,你也不用改任何代碼和配置,這就是日志門面的好處。
到此這篇關(guān)于SpringBoot整合日志功能(slf4j+logback)詳解的文章就介紹到這了,更多相關(guān)SpringBoot整合slf4j+logback內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺析Java設(shè)計模式編程中的單例模式和簡單工廠模式
這篇文章主要介紹了淺析Java設(shè)計模式編程中的單例模式和簡單工廠模式,使用設(shè)計模式編寫代碼有利于團隊協(xié)作時程序的維護,需要的朋友可以參考下2016-01-01maven引入mysql-connector-java包失敗的解決方案
這篇文章主要介紹了maven引入mysql-connector-java包失敗的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02Java多線程之JUC(java.util.concurrent)的常見類(多線程編程常用類)
這篇文章主要給大家介紹了關(guān)于Java多線程之JUC(java.util.concurrent)的常見類(多線程編程常用類)的相關(guān)資料,Java中的JUC(java.util.concurrent)包提供了一些并發(fā)編程中常用的類,這些類可以幫助我們更方便地實現(xiàn)多線程編程,需要的朋友可以參考下2024-02-02Spring Boot調(diào)用 Shell 腳本實現(xiàn)看門狗功能
這篇文章主要介紹了Spring Boot調(diào)用 Shell 腳本實現(xiàn)看門狗功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06PowerJob的OhMyClassLoader工作流程源碼解讀
這篇文章主要介紹了PowerJob的OhMyClassLoader工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01