SpringBoot第十三篇:日志處理


作者:追夢1819
原文:https://www.cnblogs.com/yanfei1819/p/10973583.html
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


## 引言

  日志是軟件系統的“基礎設施”,它可以幫助我們了解系統的運行軌跡,查找系統的運行異常等。很多人都沒有引起對日志的重視。

下面我們先來設定幾個實際項目項目的場景:

1、xxx物流雲系統,公司在給貨車司機打款的時候,司機沒收到賬款。司機在線等,沒收到賬款,就不繼續跑了;

2、xxx商城小程序,給用戶進行退款的時候,用戶沒有收到錢,然后要舉報公司。。。;

3、線上系統掛了,待找原因,待上線等。

  這些都屬於很嚴重的生產事故了,直接影響公司的運營。然而,這些問題的解決,通常在要日志中查找原因(當然,日志的作用不限於此),然后解決。

  我們見過最多的日志相關的代碼莫過於System.out.println("");log4j 這兩種了。下面我們來說說 SpringBoot 中日志框架的使用。


## 日志框架介紹

目前市面上的日志框架有:

JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j....

log4j

  log4j 是 Apache 的一個開放源代碼項目,通過使用Log4j,我們可以控制日志信息輸送的目的地是控制台、文件、數據庫等;我們也可以控制每一條日志的輸出格式;通過定義每一條日志信息的級別,我們能夠更加細致地控制日志的生成過程。
Log4j有7種不同的log級別,按照等級從低到高依次為:TRACE<DEBUG<INFO<WARN<ERROR<FATAL<OFF。如果配置為OFF級別,表示關閉 log。

  Log4j支持兩種格式的配置文件:properties和xml。

  包含三個主要的組件:Logger、appender、Layout。

slf4j

  slf4j,即簡單日志門面(Simple Logging Facade for Java),不是具體的日志解決方案,而是通過Facade Pattern提供一些Java logging API,它只服務於各種各樣的日志系統。按照官方的說法,SLF4J是一個用於日志系統的簡單Facade,允許最終用戶在部署其應用時使用其所希望的日志系統。作者創建SLF4J的目的是為了替代Jakarta Commons-Logging。
實際上,slf4j 所提供的核心API是一些接口以及一個 LoggerFactory 的工廠類。在使用 slf4j 的時候,不需要在代碼中或配置文件中指定你打算使用那個具體的日志系統。slf4j 提供了統一的記錄日志的接口,只要按照其提供的方法記錄即可,最終日志的格式、記錄級別、輸出方式等通過具體日志系統的配置來實現,因此可以在應用中靈活切換日志系統。

適用場景:
  如果你開發的是類庫或者嵌入式組件,那么就應該考慮采用 slf4j,因為不可能影響最終用戶選擇哪種日志系統。在另一方面,如果是一個簡單或者獨立的應用,確定只有一種日志系統,那么就沒有使用 slf4j 的必要。假設你打算將你使用 log4j 的產品賣給要求使用 JDK 1.4 Logging 的用戶時,面對成千上萬的 log4j 調用的修改,相信這絕對不是一件輕松的事情。但是如果開始便使用slf4j,那么這種轉換將是非常輕松的事情。

logback

  Logback,一個“可靠、通用、快速而又靈活的Java日志框架”。

  logback當前分成三個模塊:logback-core,logback- classic和logback-access。logback-core 是其它兩個模塊的基礎模塊。logback-classic 是 log4j 的一個改良版本。此外logback-classic 完整實現 SLF4J API 使你可以很方便地更換成其它日志系統如log4j或JDK14 Logging。logback-access 訪問模塊與 Servlet 容器集成提供通過Http來訪問日志的功能。

  Java提供了自己的日志框架,類似於 slf4j,但是API並不完善,對開發者不是很友好,而且對於日志的級別分類也不是很清晰,比如:SEVERE, WARNING, INFO, CONFIG, FINE,FINER, FINEST。所以不推薦使用這種方式輸出日志。

JCL

  Jakarta Commons Logging 和 slf4j 非常類似,也是提供的一套API來掩蓋了真正的 logger 實現。便於不同的 logger 的實現的替換,而不需要重新編譯代碼。缺點在於它的查找 logger 的實現者的算法比較復雜,而且當出現了一些class loader之類的異常時,無法去修復它。

Log4j 2

  已經有很多其他的日志框架對 slf4j 進行了改良,比如說 slf4j、logback 等。而且 log4j2 在各個方面都與 logback 非常相似,那么為什么我們還需要 log4j2 呢?

  1. 插件式結構。log4j2 支持插件式結構。我們可以根據自己的需要自行擴展 log4j2 , 我們可以實現自己的 appender、logger、filter;
  2. 配置文件優化。在配置文件中可以引用屬性,還可以直接替代或傳遞到組件。而且支持json格式的配置文件。不像其他的日志框架,它在重新配置的時候不會丟失之前的日志文件;
  3. Java 5 的並發性。log4j2 利用Java 5中的並發特性支持,盡可能地執行最低層次的加鎖。解決了在 log4j1.x 中存留的死鎖的問題。如果你的程序仍然在飽受內存泄露的折磨,請毫不猶豫地試一下 log4j2 吧;
  4. 異步 logger。log4j2 是基於 LMAX Disruptor庫的。在多線程的場景下,和已有的日志框架相比,異步的 logger 擁有10左右的效率提升。

SpringBoot默認日志框架

默認配置

SpringBoot 默認使用的是 logback 日志系統,需要引入 maven 依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
</dependency>

下面我們看看底層的依賴關系:

由上圖可以得到幾個結論:

  • SpringBoot 底層也是使用 slf4j+logback 的方式進行日志記錄;
  • SpringBoot也把其他的日志都替換成了slf4j;

我們在啟動類做一個簡單的測試,觀察效果:

@SpringBootApplication
public class LogDemoApplication {
    private static final Logger logger = LoggerFactory.getLogger(LogDemoApplication.class);
    public static void main(String[] args) {
        logger.info("hello,logback!");
        SpringApplication.run(LogDemoApplication.class, args);
    }
}

  以上代碼關於 LoggerFactory.getLogger() 方法中的參數 Clazz.class,主要是准確編寫class信息能夠提供快速定位日志的效率。即可以在日志中款速定位到要查找的內容。

啟動程序,能夠看到打印的日志:

自定義配置

  以上的示例中,都是用的 SpringBoot 默認的日志屬性,當然,這些屬性可修改,下圖是屬性列表,可以根據自己的需求進行自定義。

針對屬性中關於日志格式的符號定義,此處也做一個簡單的說明:

%d{HH:mm:ss.SSS}——日志輸出時間
%thread——輸出日志的進程名字,這在Web應用以及異步任務處理中很有用
%-5level——日志級別,並且使用5個字符靠左對齊
%logger- ——日志輸出者的名字
%msg——日志消息
%n——平台的換行符

日志持久化

  以上示例是將日志打印到控制台。在實際項目中,日志通常是進行持久化,存儲在文件中或者數據庫中。

一、存儲在文件中

只要在 application.properties 或者 application.yml 中配置以下屬性:

# 日志路徑
logging.path=
# 日志名稱
logging.file=SpringBoot.log

二、存入數據庫

這種方式就是醒目中的添加業務了。通常用的不多。


## SpringBoot與其他日志框架

  SpringBoot 默認使用的日志框架是 logback + slf4j ,如果想與其它的日志框架整合,則必須將默認的日志框架排除:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

與 log4j2 整合:

首先,引入 maven 依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

其次,log4j2.xml配置:

<?xml version="1.0" encoding="UTF-8"?>  
<Configuration status="WARN">  
    <Properties>
        <property name="LOG_PATH">../logs/</property>
        <property name="LOG_FILE">testlog4j2</property>
    </Properties>
    <Appenders>  
        <Console name="Console" target="SYSTEM_OUT">  
            <PatternLayout>  
                <pattern>%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] - %m%n</pattern>  
            </PatternLayout>  
        </Console>  
        <RollingFile name="errorlogfile" fileName="${LOG_PATH}/${LOG_FILE}.log"
                  filePattern="${LOG_PATH}/$${date:yyyy-MM}/${LOG_FILE}-%d{yyyy-MM-dd HH-mm}-%i.log">
          <PatternLayout> 
            <pattern>%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] - %m%n</pattern>
          </PatternLayout>  
          <Policies>  
                <TimeBasedTriggeringPolicy />  
                <SizeBasedTriggeringPolicy size="50 MB" />  
          </Policies>  
          <DefaultRolloverStrategy max="20" />  
        </RollingFile>  
    </Appenders>  
    <Loggers> 
        <root level="info">    
          <AppenderRef ref="Console"/>  
          <AppenderRef ref="errorlogfile" /> 
        </root>    
    </Loggers>  
</Configuration>  

第三步,在 application.properties 中指定配置文件的位置:

logging.config= classpath:log4j2.xml

第四步,在啟動類中測試:

@SpringBootApplication
public class LogOtherDemoApplication {
    private static Logger logger = LogManager.getLogger(LogOtherDemoApplication.class);
    public static void main(String[] args) {
        logger.info("這里是整合其他日志框架");
        SpringApplication.run(LogOtherDemoApplication.class, args);
    }
}

最后,啟動項目,可以看到對應的日志和日志文件。


總結

  日志框架適用很廣泛,而且涉及的內容內多,本章只做了日志介紹和適用的闡述。后續還涉及很多的內容,比如如何進行日志檢索、如何進行日志清洗等。由於篇幅所限,本章不做過多的介紹。
  源碼:我的GitHub


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM