Spring Boot 日誌框架

(一)門面模式

在平常的系統開發中,日誌起到了重要的作用,日誌寫得好對於線上問題追蹤有着很大的幫助。一個好的日誌框架,既要方便易用,也要有較好的性能,減少日誌輸出對系統內存、CPU 的影響。
在學習 Spring Boot 的日誌框架之前,我們有必要先了解一下日誌框架的設計模式——門面模式。在軟件開發領域有這樣一句話:計算機科學領域的任何問題都可以通過增加一個間接的中間層來解決。而門面模式就是對於這句話的典型實踐。
門面模式
門面模式,是面向對象設計模中的結構模式,又稱爲外觀模式。外部與一個子系統的通信必須通過一個統一的外觀對象進行,爲子系統中的一組接口提供一個一致的界面,外觀模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
使用門面模式的好處是,接口和實現分離,屏蔽了底層的實現細節。
當你使用 slf4j 作爲系統的日誌門面時,底層具體實現可以使用 log4j、logback、log4j2 中的任意一個。
就像前面介紹的幾種日誌框架一樣,每一種日誌框架都有自己單獨的API,要使用對應的框架就要使用其對應的API,這就大大的增加應用程序代碼對於日誌框架的耦合性。
爲了解決這個問題,就是在日誌框架和應用程序之間架設一個溝通的橋樑,對於應用程序來說,無論底層的日誌框架如何變,都不需要有任何感知。只要門面服務做的足夠好,隨意換另外一個日誌框架,應用程序不需要修改任意一行代碼,就可以直接上線。簡而言之,門面模式解除了應用和日誌框架之間的耦合。

(二)Java 常用的日誌框架

Java 中常用的日誌框架如下:

  • log4j(Log for Java):Apache 的一個開源項目,七種日誌級別:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE.
  • logback:是一個很成熟的日誌框架,其實 logBack 和 log4j 出自一個人之手,這個人就是 Ceki Gülcü。logback 比 log4j 大約快 10 倍、消耗更少的內存,遷移成本也很低,自動壓縮日誌、支持多樣化配置、不需要重啓就可以恢復 I/O 異常等優勢。
  • log4j2:作者認爲,log4j2已經不僅僅是 log4j 的一個升級版本了,而是從頭到尾被重寫的,甚至可以認爲就是完全不同的兩個框架。

Spring Boot 默認使用 logback,但相比較而言,log4j2 在性能上面會更好。SpringBoot 高版本都不再支持 log4j,而是支持 log4j2。log4j2,在使用方面與 log4j 基本上沒什麼區別,比較大的區別是 log4j2 不再支持 properties 配置文件,支持 xml、json 格式的文件。

(三)理解 SLF4J

阿里巴巴Java開發手冊》中對日誌框架的規約如下:

應用中不可直接使用日誌系統 (Log4j 、 Logback) 中的 API ,而應依賴使用日誌框架。
SLF4J 中的 API ,使用門面模式的日誌框架,有利於維護和各個類的日誌處理方式統一。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Test.class);

Java 簡易日誌門面(Simple Logging Facade for Java,縮寫 SLF4J),它並不是真正的日誌框架,他是對所有日誌框架制定的一種規範、標準、接口,並不是一個框架的具體的實現,因爲接口並不能獨立使用,需要和具體的日誌框架實現配合使用。可以在軟件部署的時候決定要使用的 Logging 框架,目前主要支持的有 Java logging API、log4j 及 logback 等框架。
接口用於定製規範,可以有多個實現,使用時是面向接口的(導入的包都是 slf4j 的包而不是具體某個日誌框架中的包),即直接和接口交互,不直接使用實現,所以可以任意的更換實現而不用更改代碼中的日誌相關代碼。
比如:slf4j 定義了一套日誌接口,項目中使用的日誌框架是logback,開發中調用的所有接口都是 slf4j 的,不直接使用 logback,調用是 自己的工程調用 slf4j 的接口,slf4j 的接口去調用 logback 的實現,可以看到整個過程應用程序並沒有直接使用 logback,當項目需要更換更加優秀的日誌框架時(如log4j2)只需要引入 log4j2 的 jar 和 Log4j2 對應的配置文件即可,完全不用更改 Java 代碼中的日誌相關的代碼 logger.info(“xxx”),也不用修改日誌相關的類的導入的包 import org.slf4j.Logger; import org.slf4j.LoggerFactory;

(四)框架性能

Apache 官網對 Log4j 和 Logback 的性能評測如下圖所示:
日誌吞吐量評測
響應時間評測

(五)引入 Log4j2

在 Spring Boot 中我們一般使用 Lombok 的 @Slf4j 註解來取代私有靜態日誌常量的創建,在類上引入 @Slf4j 註解後,使用 log 常量打印日誌即可:log.info("xxx") / log.error("xxx")
如果想要在 Spring Boot 中使用高性能的 Log4j2,那麼需要首先排除 Spring Boot 默認的日誌框架依賴,再引入 Log4j2 依賴。

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <!-- 去掉logback配置 -->
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- 引入log4j2依賴 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
</dependencies>

(六)參考博客

  1. Spring Boot 實戰 —— 日誌框架 Log4j2 SLF4J 的學習
  2. Spring Boot 實戰 —— 日誌框架 logback 的學習
  3. Log4j2的性能爲什麼這麼好?
  4. SpringBoot 是如何實現日誌的?
  5. Java 日誌框架解析:設計模式、性能
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章