Spring Boot與日誌
阿新 • • 發佈:2020-09-10
[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,使用其他包替換原有日誌框架,替換的意思就是,例如要把原框架裡面對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() {
/**
* 日誌的級別
* 由低到高
### 圖解 - 如果系統中只匯入了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)