SpringBoot日誌實現
SpringBoot日誌實現
SpringBoot預設的日誌實現是使用slf4j
+logback
,這種實現類似於JDBC + 資料庫驅動(統一介面+實現類)。
slf4j叫做日誌門面,是一個統一的日誌介面層,各種具體的日誌實現都可以通過slf4j來實現,比如logback就是一個具體的日誌門面的實現。
市面上常見的日誌框架有:JUL , JCL , Jboss-logging , logback , log4j , log4j2 , slf4j等等,他們的分類如下:
日誌門面(日誌的抽象層) | 日誌實現 |
---|---|
JCL(Jakarta Commons Logging) , SLF4J(Simple Logging Facade for Java), Jboss-logging | Log4j , JUL(java.util.logging ) , Log4j2, Logback |
JCL是Apache公司開發的一個框架,Jakarta小組開發的,Spring Framework在使用,但是2014年已經停止更新了。SLF4J , Log4j , Logback是同一個人寫的,這個人想優化Log4j,但是認為重新寫比較麻煩,於是寫了SLF4J這個抽象層日誌框架,又寫了Logback這個實現類。Log4j2也是Apache公司的,好多框架都沒適配。Hibernate底層使用Jboss-logging實現。
我們需要在左邊選一個門面(抽象層),右邊選一個實現。
通過Slf4j的LoggerFactory
建立Logger
來進行日誌的記錄;
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官網:https://www.slf4j.org/
下圖是使用slf4j如何實現各種日誌框架:
可以看到,只引入slf4j是不能夠實現日誌記錄的,在引入slf4j-api.jar的基礎上;
如果要實現logback日誌框架,需要引入logback-core.jar和logback-classic.jar;
如果要實現log4j日誌框架,需要引入slf4j-log412.jar(log4j適配slf4j的jar),log4j.jar。其他情況類似。
**每一個日誌實現框架都有自己的配置檔案,使用slf4j以後,配置檔案還是做成日誌實現框架自己本身的配置檔案。**比如實現框架選用logback,那麼配置檔案就寫logback.xml這種,實現框架選log4j,那麼配置問價就選log4j.xml這種。
但是在實際專案中,我們所引入的不同框架的底層日誌框架是不一樣的。比如:
Spring使用JCL,Hibernate使用Jboss等等,我們就需要統一日誌記錄,讓不同的框架統一使用slf4j進行輸出,這樣我們就不用寫別的配置檔案,統一使用logback進行配置。具體做法如下圖:
如上圖,比如Spring框架,為了達到上述目標,我們需要排除掉Spring底層的commons-logging包,(不引入Spring會報包找不到的錯誤)然後引入包裝層jcl-over-slf4j,這個包裝層jar的包路徑,類名等都採用commons-logging的形式進行配置,但是底層實現是slf4j,最後新增logback的jar包。
統一日誌記錄的思路(SpringBoot實現統一日誌記錄為slf4j的做法):
-
先排除掉其他日誌框架
-
然後用中間包來替換排除掉的日誌框架
-
最後再新增目標日誌框架
注意:在SpringBoot2.x版本的時候,上述的實現方式發生了一些改變,中間引入了"橋接"的概念,沒有直接通過模擬類名實現,比如類:
SLF4JBridgeHandler
,但是其底層的實現方法都是類似的,都是通過排除原有依賴實現,比如spring-boot-starter-logging的依賴:
JUL的橋接模式的實現是繼承JUL的Handler抽象類,按原始碼上的註釋所說,是實現一種redirected重定向。
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.11.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.26</version>
<scope>compile</scope>
</dependency>
注意實現由log4j-over-slf4j變成了log4j-to-slf4j
但是其底層依然不變,還是排除jar包,比如spring-boot底層引入的Apache的commons包:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.5.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
<optional>true</optional>
</dependency>
其中關於JCL日誌框架的處理是使用spring-jcl這個工程進行處理,整個spring-core都依賴於這個工程。
[外鏈圖片轉存失敗(img-O5dMxV5I-1566862162637)(/Users/circleus/Library/Application Support/typora-user-images/image-20190407221811598.png)]
當SpringBoot引入新框架的時候,如果此框架使用了JUL,JCL,或者log4j,這個時候我們應該排除掉原來的日誌框架,避免因為現在SpringBoot中存在相同的日誌實現而造成jar包衝突衝突。
SpringBoot預設是info級別,如果沒有指定級別就使用 info 級別,這個預設級別也叫 root級別,想要調整某個包的日誌級別可以通過application.properties進行配置,例:
# com.anhe是我自己的包路徑
logging.level.com.anhe=trace
有時候想檢視Mybatis執行的具體sql語句可以將mapper對應的包路徑日誌級別設定為debug級別。
logging.file | logging.path | Example | Description |
---|---|---|---|
未配置 | 未配置 | 只在控制檯輸出 | |
指定檔名 | 未配置 | my.log | 輸出日誌到my.log檔案 |
未配置 | 指定目錄 | /var/log | 輸出到指定目錄的spring.log檔案中 |
指定檔名 | 指定目錄 | /Users/circleus/Documents/tmp /Users/circleus/Documents/my.log | 都指定的時候以logging.file為準 |
# 配置在指定目錄,不指定路徑的時候就是配置在專案路徑下
logging.file=/Users/circleus/Documents/my.log
# 在控制檯輸出的日誌的格式
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
此路徑配置的xml配置了專案關於日誌的預設配置:spring-boot/2.1.4.RELEASE/spring-boot-2.1.4.RELEASE.jar!/org/springframework/boot/logging/logback/defaults.xml
除此之外,還可以配置日誌滾動條件:比如配置日誌檔案滿10M就記錄到下一個檔案,檔名以i遞增,或者按天進行滾動。日誌配置檔案的名稱:logback-spring.xml
或者logback.xml
,推薦使用logback-spring.xml
,因為配置成logback-spring.xml
是由SpringBoot自己載入,不是由日誌框架直接載入,可以使用高階特性:,通過這個特性,可以配置不同環境配置不同的日誌級別,比如開發環境使用debug,生產環境使用info。
相關文章
- SpringBoot | SpringBoot 是如何實現日誌的?Spring Boot
- SpringBoot 實現整合log4j2日誌Spring Boot
- Springboot AOP 自定義註解實現系統日誌Spring Boot
- SpringBoot 日誌框架Spring Boot框架
- SpringBoot日誌管理Spring Boot
- springboot日誌篇Spring Boot
- SpringBoot進階教程 | 第二篇:日誌元件logback實現日Spring Boot元件
- SpringBoot裡slf4j日誌功能的預設實現Spring Boot
- SpringBoot 實戰 (七) | 預設日誌配置Spring Boot
- SpringBoot2 整合日誌,複雜業務下的自定義實現Spring Boot
- 55.SpringBoot日誌Spring Boot
- Springboot日誌相關Spring Boot
- Yii使用DbTarget實現日誌功能
- 使用 Serverless 實現日誌報警Server
- .Net Core 審計日誌實現
- Rust 實現日誌記錄功能Rust
- springboot+MDCAdapter自定義starter實現日誌全鏈路追蹤Spring BootAPT
- SpringBoot使用ELK日誌收集Spring Boot
- SpringBoot專案整合日誌Spring Boot
- logstash收集springboot日誌Spring Boot
- Springboot漫遊日誌(1)Spring Boot
- Flume 實現自己的實時日誌(2)
- 從零開始實現放置遊戲(五)——實現掛機戰鬥(3)引入日誌功能並實現切面日誌遊戲
- Springboot+logback+druid +密碼加密 實現業務日誌入庫Spring BootUI密碼加密
- 日誌模組(一標頭檔案就實現了日誌記錄)
- hyperf 如何實現按日期分割日誌
- 分散式 | DBLE 的 general 日誌實現分散式
- 【shell】實現tomcat日誌切割功能Tomcat
- SpringBoot多環境日誌配置Spring Boot
- go開發屬於自己的日誌庫-檔案日誌庫實現Go
- SpringBoot指定日誌檔案和日誌Profile功能Spring Boot
- 實訓日誌
- 利用oracle的日誌挖掘實現回滾Oracle
- Django實現web端tailf日誌檔案DjangoWebAI
- 雲端日誌服務——UPLOG的實現
- PHP實現日誌寫入log.txtPHP
- Spring AOP 實現業務日誌記錄Spring
- Java 日誌快取機制的實現Java快取