1. 程式人生 > >Spring Boot與日誌

Spring Boot與日誌

[TOC](目錄) ## 1、日誌框架 故事:有一個開發人員,開發一個大型系統; > 遇到重要資料,喜歡`System.out.println("")`,將關鍵資料列印在控制檯 > > 去掉?寫在一個檔案?方便? > > 框架來記錄系統的一些執行時資訊,日誌框架:first.jar > > 高大上的幾個功能?非同步模式?自動規定?等等?:second.jar > > 將以前的框架卸下來?換上新的框架,更新修改之前相關API:third.jar > > JDBC---資料庫驅動: > > - 寫了一個統一的介面層:暫時叫做日誌門面(日誌的一個抽象層):fourth.jar > - 給專案中匯入具體的日誌實現就行了,我們之前的日誌框架都是實現的抽象層 ## 2、市面上的日誌框架 JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j... ### 2.1 下表行間無任何對應關係 | 日誌門面 | 日誌實現 | | -------------------------------------- | ------------------------ | | JCL( Jakarta Commons Logging) | Log4j | | SLF4j( Simple Logging Facade for Java) | JUL( java. util.logging) | | jboss-logging | Log4j2 | | | Logback | 左邊選一個門面(抽象層)、右邊選一個實現 選哪個呢?排除法 ### 2.2 日誌門面:slf4j Jboss-logging:普通程式設計師用不了 JCL:最後一次更新是在2014年,廉頗老矣,尚能飯否? 剩下slf4j理所應當 ### 2.3 日誌實現:logback log4j、logback和slf4j都是一個人寫的,適配性好,log4j不錯但有效能問題,但升級消耗太大,就重寫了logback 所有log4j沒有logback先進,JUL是Java自帶的,怕日誌市場被佔,比較簡略 log4j2是借log4j之名,由Apache公司重新做的框架,設計地非常好,由於太好還沒適配 ### 2.4 Spring Boot怎麼做的呢? Spring框架預設是用JCL日誌框架 Spring Boot選用slf4j和logback ## 3、slf4j的使用 如何在系統中使用slf4j?[官方文件](http://www.slf4j.org/) - 以後開發的時候,日誌記錄方法得呼叫,不應該來直接呼叫日誌的實現類,而是呼叫日誌抽象層裡面的方法 - 參見使用者手冊[SLF4J user manual](http://www.slf4j.org/manual.html)給系統中匯入slf4j的jar和logback的實現jar ```java 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"); } } ``` > 雖然預設用的是logback的實現,如果想要其他實現也可以,畢竟slf4j是抽象層,實現用什麼都行

### 圖解 - 如果系統中只匯入了slf4j,我們要進行日誌記錄,就會返回空值,因為沒有任何實現 - 正確用法:我的應用程式面向slf4j程式設計,呼叫它的方法進行日誌記錄,在程式中也匯入日誌實現,雖然呼叫slf4j介面,但logback會實現,記錄到檔案或控制檯 - 如果slf4j要繫結log4j,log4j出現比較早,沒想到要適配slf4j,所以兩者繫結要有一個適配層(slf4j實現的),適配層相當於上面實現了slf4j的具體方法,而在方法裡面要進行真正日誌記錄的時候,又調了log4j的API,要用log4j還要匯入適配層即可 JUL同理 - slf4j也有簡單日誌實現也能用,或者slf4j沒有什麼操作的實現包,也是輸出空值 - 每一個日誌的實現框架都有自己的配置檔案,使用slf4j以後,配置檔案還是做成日誌實現框架自己本身的配置檔案 - slf4j只提供抽象層,用哪個實現就寫那個的配置檔案 ## 4、遺留問題 開發某個系統時:使用{slf4j+logback},依賴Spring框架(commons-logging),依賴Hibernate框架(Jboss-logging),依賴MyBatis框架等等可能一大堆 出現什麼問題,系統中日誌雜交? 現在就要做同一日誌記錄,即使是別的框架和我一起使用slf4j進行輸出? 進入[slf4j官方文件](http://www.slf4j.org/)的[legacy APIs](http://www.slf4j.org/legacy.html)

統一slf4j,使用其他包替換原有日誌框架,替換的意思就是,例如要把原框架裡面對Commons-logging的依賴排除掉 但如果我現在用的Spring框架缺少Commons-logging就執行不起來了,Spring底層記錄日誌就需要Commons-logging,那怎麼辦呢?就用jcl-over-slf4j.jar替換這個包,Spring要用的類這個替換包例還是有的,就不會報錯了 但新的包實現怎麼辦呢?新的包調入slf4j,二slf4j又調到真正的實現中,其他框架不同日誌框架同理替換 其他組合方式也是如此 如何讓系統中所有的日誌都同一到slf4j: - 將系統中其他日誌框架先排除去; - 用中間包來替換原有的日誌框架 - 我們匯入slf4j其他的實現 ## 5、Spring Boot日誌關係 每個啟動器(場景)都要依賴的 ```xml ``` Spring Boot使用它來做日誌功能 ```xml ``` 依賴圖示:

總結: - Spring Boot底層也是使用slf4j+logback的方式進行日誌記錄 - Spring Boot也是把其他的日誌都替換成了slf4j - 中間替換包,以`jcl-over-slf4j.jar`為例: 在專案的依賴包中找到其對應jar包:(中間轉換包) ![Spring Boot](https://gitee.com/mysteryguest/ObjectStorage/raw/master/Spring/jcl-over-slf4j.PNG) - 從圖中看出,雖然包名用的Apache的,但實現卻是使用的`SLF4JLogFactory()`的日誌工廠 ```java @SuppressWarnings("rawtypes") public abstract class LogFactory { static String UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J = "http://www.slf4j.org/codes.html#unsupported_operation_in_jcl_over_slf4j"; static LogFactory logFactory = new SLF4JLogFactory(); ... } ``` - 如果我們要引入其他框架?一定要把這個框架的預設日誌依賴移除掉! Spring框架用的是commons-logging: ```xml ``` Spring Boot能自動適配所有的日誌,而且底層使用slf4j+logback的方式記錄日誌,我們唯一需要做的是,引入其他框架的時候,只需要把這個框架依賴的日誌框架排除掉。 ## 6、日誌使用 ### 6.1 預設配置 當我們初始化專案執行後,自己沒有配置日誌,但控制檯是由輸出資訊的 Spring Boot預設幫我們配置好了日誌,直接使用就可以了 ```java // LoggerFactory是記錄器工廠,記錄器 Logger logger = LoggerFactory.getLogger(getClass()); @Test public void testLog() { /** * 日誌的級別 * 由低到高