文章已經收錄在 Github.com/niumoo/JavaNotes ,更有 Java 程序員所須要掌握的核心知識,歡迎Star和指教。
歡迎關注個人 公衆號,文章每週更新。注意:本 Spring Boot 系列文章基於 Spring Boot 版本 v2.1.1.RELEASE 進行學習分析,版本不一樣可能會有細微差異。html
Spring 框架選擇使用了 JCL 做爲默認日誌輸出。而 Spring Boot 默認選擇了 SLF4J 結合 LogBack。那咱們在項目中該使用哪一種日誌框架呢?在對於不一樣的第三方 jar 使用了不一樣的日誌框架的時候,咱們該怎麼處理呢?
<!-- more -->java
日誌對於應用程序的重要性不言而喻,不論是記錄運行狀況仍是追蹤線上問題,都離不開對日誌的分析,在 Java 領域裏存在着多種日誌框架,如 JUL, Log4j, Log4j2, Commons Loggin, Slf4j, Logback 等。關於 Log4j, Log4j2 和 Slf4j 直接的故事這裏不作介紹,有興趣能夠自行百度。git
在開發的時候不該該直接使用日誌實現類,應該使用日誌的抽象層。具體參考 SLF4J 官方。
下圖是 SLF4J 結合各類日誌框架的官方示例,從圖中能夠清晰的看出 SLF4J API 永遠做爲日誌的門面,直接應用與應用程序中。程序員
同時 SLF4 官方給出了簡單示例。github
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HelloWorld { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(HelloWorld.class); logger.info("Hello World"); } }
須要注意的是,要爲系統導入 SLF4J 的 jar 和 日誌框架的實現 jar. 因爲每個日誌的實現框架都有本身的配置文件,因此在使用 SLF4 以後,配置文件仍是要使用實現日誌框架的配置文件。web
通常狀況下,在項目中存在着各類不一樣的第三方 jar ,且它們的日誌選擇也可能不盡相同,顯然這樣是不利於咱們使用的,那麼若是咱們想爲項目設置統一的日誌框架該怎麼辦呢?面試
在 SLF4J 官方,也給了咱們參考的例子。spring
從圖中咱們獲得一種統一日誌框架使用的方式,可使用一種和要替換的日誌框架類徹底同樣的 jar 進行替換,這樣不至於原來的第三方 jar 報錯,而這個替換的 jar 其實使用了 SLF4J API. 這樣項目中的日誌就均可以經過 SLF4J API 結合本身選擇的框架進行日誌輸出。
統一日誌框架使用步驟概括以下:shell
根據上面總結的要統一日誌框架的使用,第一步要排除其餘的日誌框架,在 Spring Boot 的 Maven 依賴裏能夠清楚的看到 Spring Boot 排除了其餘日誌框架。咱們自行排除依賴時也只須要按照圖中的方式就行了。apache
其實 Spring Boot 也是使用了 SLF4J+logback 的日誌框架組合,查看 Spring Boot 項目的 Maven 依賴關係能夠看到 Spring Boot 的核心啓動器 spring-boot-starter 引入了 spring-boot-starter-logging.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> <version>2.1.1.RELEASE</version> <scope>compile</scope> </dependency>
而 spring-boot-starter-logging 的 Maven 依賴主要引入了 logback-classic (包含了日誌框架 Logback 的實現),log4j-to-slf4j (在 log4j 日誌框架做者開發此框架的時候尚未想到使用日誌抽象層進行開發,所以出現了 log4j 向 slf4j 轉換的工具),jul-to-slf4j ( Java 自帶的日誌框架轉換爲 slf4j).
<dependencies> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-to-slf4j</artifactId> <version>2.11.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.25</version> <scope>compile</scope> </dependency> </dependencies>
從上面的分析,Spring Boot 對日誌框架的使用已是清晰明瞭了,咱們使用 IDEA 工具查看 Maven 依賴關係,能夠清晰的看到日誌框架的引用。若是沒有 IDEA 工具,也可使用 Maven 命令查看依賴關係。
mvn dependency:tree
因而可知,Spring Boot 能夠自動的適配日誌框架,並且底層使用 SLF4 + LogBack 記錄日誌,若是咱們自行引入其餘框架,須要排除其日誌框架。
從上面的分析,發現 Spring Boot 默認已經使用了 SLF4J + LogBack . 因此咱們在不進行任何額外操做的狀況下就可使用 SLF4J + Logback 進行日誌輸出。
編寫 Java 測試類進行測試。
import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; /** * <p> * 測試日誌輸出, * SLF4J 日誌級別從小到大trace,debug,info,warn,error * * @Author niujinpeng * @Date 2018/12/11 21:12 */ @RunWith(SpringRunner.class) @SpringBootTest public class LogbackTest { Logger logger = LoggerFactory.getLogger(getClass()); @Test public void testLog() { logger.trace("Trace 日誌..."); logger.debug("Debug 日誌..."); logger.info("Info 日誌..."); logger.warn("Warn 日誌..."); logger.error("Error 日誌..."); } }
已知日誌級別從小到大爲 trace < debug < info < warn < error . 運行獲得輸出以下。因而可知 Spring Boot 默認日誌級別爲 INFO.
2018-12-11 23:02:58.028 [main] INFO n.c.boot.LogbackTest - Info 日誌... 2018-12-11 23:02:58.029 [main] WARN n.c.boot.LogbackTest - Warn 日誌... 2018-12-11 23:02:58.029 [main] ERROR n.c.boot.LogbackTest - Error 日誌...
從上面的日誌結合 Logback 日誌格式能夠知道 Spring Boot 默認日誌格式是。
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n # %d{yyyy-MM-dd HH:mm:ss.SSS} 時間 # %thread 線程名稱 # %-5level 日誌級別從左顯示5個字符寬度 # %logger{50} 類名 # %msg%n 日誌信息加換行
至於爲何 Spring Boot 的默認日誌輸出格式是這樣?咱們能夠在 Spring Boot 的源碼裏找到答案。
能夠直接在配置文件編寫日誌相關配置。
# 日誌配置 # 指定具體包的日誌級別 logging.level.net.codingme=debug # 控制檯和日誌文件輸出格式 logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n # 日誌文件大小 logging.file.max-size=10MB # 保留的日誌時間 logging.file.max-history=10 # 日誌輸出路徑,默認文件spring.log logging.path=systemlog #logging.file=log.log
關於日誌的輸出路徑,可使用 logging.file 或者 logging.path 進行定義,二者存在關係以下表。
logging.file |
logging.path |
例子 | 描述 |
---|---|---|---|
(沒有) | (沒有) | 僅控制檯記錄。 | |
具體文件 | (沒有) | my.log |
寫入指定的日誌文件,名稱能夠是精確位置或相對於當前目錄。 |
(沒有) | 具體目錄 | /var/log |
寫入spring.log 指定的目錄,名稱能夠是精確位置或相對於當前目錄。 |
由於 Log4j 日誌框架已經年久失修,原做者都以爲寫的很差,因此下面演示替換日誌框架爲 Log4j2 的方式。根據官網咱們 Log4j2 與 logging 須要二選一,所以修改 pom以下。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <artifactId>spring-boot-starter-logging</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
文章代碼已經上傳到 GitHub Spring Boot 日誌系統。
最後的話
文章已經收錄在 Github.com/niumoo/JavaNotes ,歡迎Star和指教。更有一線大廠面試點,Java程序員須要掌握的核心知識等文章,也整理了不少個人文字,歡迎 Star 和完善,但願咱們一塊兒變得優秀。
文章有幫助能夠點個「贊」或「分享」,都是支持,我都喜歡!
文章每週持續更新,要實時關注我更新的文章以及分享的乾貨,能夠關注「 未讀代碼 」公衆號或者個人博客。