日誌系列1——slf4j日誌框架原理
阿新 • • 發佈:2020-05-14
[toc]
### 1.前言
說到日誌工具,日常工作或學習中肯定聽過這些名詞:log4j、logback、jdk-logging、slf4j、commons-logging等,它們之間有什麼關係,在整個日誌體系中又扮演什麼角色呢?
日誌框架分為三大類,包括日誌門面、日誌介面卡、日誌庫。利用門面設計模式,即Facade來進行解耦,使日誌使用變得更簡單。
![img](https://img2020.cnblogs.com/blog/708732/202005/708732-20200513003448681-221199879.png)
### 2.日誌門面
門面設計模式是面向物件設計模式中的一種,日誌框架採用的就是這種模式,類似JDBC的設計理念。它只提供一套介面規範,自身不負責日誌功能的實現,目的是讓使用者不需要關注底層具體是哪個日誌庫來負責日誌印表機具體的使用細節等。目前用得最為廣泛的日誌門面有兩種:slf4j和commons-logging
### 3.日誌庫
它巨頭實現了日誌的相關功能,主流的日誌庫有三個,分別是log4j、log-jdk、logback。最早Java想要記錄日誌只能通過System.out或System.err來完成,非常不方便。log4j就是為了解決這一問題而提出的,它是最早誕生的日誌庫。接著JDK也在1.4版本引入了一個日誌庫java.util.logging.Logger,簡稱log-jdk。這樣市面上就出現了兩種日誌功能的實現,開發者在使用時需要關注所使用的日誌庫的具體細節。logback是最晚出現的,它與log4j出自同一個作者,是log4j的升級版且本身就實現了slf4j的介面。
### 4.日誌介面卡
日誌介面卡分為兩種場景:
1. 日誌門面介面卡,因為slf4j規範是後來提出的,在此之前的日誌庫是沒有實現slf4j的介面的,例如log4j.所以,在工程裡要想使用slf4j+log4j的模式,就額外需要一個介面卡(slf4j+log4j12)來解決介面不相容的問
2. 日誌庫介面卡,在一些老的工程裡,一開始為了開發簡單而直接使用了日誌庫API來完成日誌列印,隨著時間的推移想將原來直接呼叫日誌庫的模式改為業界標準的門面模式(例如slf4j+logback組合),但老工程程式碼裡列印日誌的地方太多,難以改動,所以需要一個介面卡來完成從舊日誌庫的API到slf4j的路由,這樣在不改動原有程式碼的情況下也能使用slf4j來統一管理日誌,而且後續自由替換具體日誌庫也不是問題。
### 5.日誌庫的選用
如果是新工程,則推薦使用slf4j+logback模式,因為logback自身實現了slf4j的介面,不需要額外引入介面卡,另外logback是log4j的升級版,具備比log4j更多的優點,可通過如下配置進行整合:
```xml
org.slf4j
slf4j-api
${slf4j-api.version}
ch.qos.logback
logback-core
${logback-core.version}
ch.qos.logback
logback-classic
${logback-classic.version}
```
如果是老工程,則需要根據所使用的日誌庫來確定門面介面卡,通常情況下老工程使用的都是log4j,因此以log4j日誌庫為例,可通過如下配置進行整合:
```xml
org.slf4j
slf4j-api
${slf4j-api.version}
org.slf4j
slf4j-log4j12
${slf4j-log4j12.version}
log4j
log4j
${log4j.version}
```
如果老程式碼直接使用了log4j日誌庫提供的介面來列印日誌,則還需要引入日誌庫介面卡,配置例項如下所示:
```xml
org.slf4j
log4j-over-slf4j
${log4j-over-slf4j.version}
```
### 6.logback.xml 配置檔案
```xml
%date %-5level %logger{80} [%X{trans_id}] - %msg%n
debug
${LOG_PATH}/logs/${application_name}/${application_name}_debug.%d{yyyy-MM-dd}_%i.log
100
10mb
%date [%thread] %-5level %logger{80} [%X{trans_id}] - %msg%n
info
${LOG_PATH}/logs/${application_name}/${application_name}_info.%d{yyyy-MM-dd}_%i.log
100
10mb
%date [%thread] %-5level %logger{80} [%X{trans_id}] - %msg%n
ERROR
ACCEPT
DENY
${LOG_PATH}/logs/${application_name}/${application_name}_error.%d{yyyy-MM-dd}_%i.log
100
10mb
%date [%thread] %-5level %logger{80} [%X{trans_id}] - %msg%n
0
256
```
例項程式碼如下:
```java
private static final Logger logger =LoggerFactory.getLogger(ConfigureQuartz.class);
```
注意,logger物件被定義為static變數,這是因為這個logger與當前類繫結,避免每次都new一個新物件,造成資源浪費,甚至引發OutOfMemoryError問題。
在使用slf4j+具體日誌庫模式時,由於slf4j相當於充當api抽象介面,所以我們的日誌列印是也是面向介面程式設計的,當我們需要更換具體的日誌庫時,我們只需要引入具體的maven依賴就可以了,並對原有的日誌庫依賴進行移除,而不需要改動程式碼。至此,slf4j的架構原理講解完成,之後會對具體的日誌庫logback的配置檔案進行講解,本章只是先簡單給出logback.xml配置檔案的基本模板,下一章節《日誌系列2——logback配置檔案詳解》敬請期待。