SpringBoot整合Logback日誌框架配置全解析

本篇要點

  • 介紹什麼是Logback
  • 介紹SpringBoot中對logging默認的配置
  • 介紹自定義logback-spring.xml的注意點

一、Logback日誌框架介紹

SpringBoot使用 Commons Logging 進行所有內部日誌的記錄,但默認配置也提供了對常用日誌的支援,如 Java Util Logging,Log4J2,和Logback. 每種logger都可以通過配置使用控制台或文件輸出日誌內容。

Logback是log4j框架的作者開發的新一代日誌框架,它效率更高、能夠適應諸多的運行環境,同時天然支援SLF4J。

二、SpringBoot與Logback

假設你使用starter啟動創建SpringBoot應用,則默認已經導入了spring-boot-starter-logging的依賴,相繼也就導入了logback所需要的依賴。

1、默認日誌格式

於是,當我們啟動SpringBoot應用時,控制台將會顯示INFO級別的日誌輸出。

可以看到,輸出內容如下:

  • 日期和時間,精確到毫秒級別。
  • 日誌級別:INFO,【日誌級別默認從高到低:ERROR,WARN,INFO,DEBUG,TRACE】。
  • 進程ID
  • 分隔符:來標識實際日誌消息的開始。
  • 執行緒名:用方括弧括起來(在控制台輸出時可能被截斷)。
  • 日誌記錄器名稱:這通常是源類名稱(通常縮寫)。
  • 日誌資訊

logback是沒有FATAL級別的,它對應的就是ERROR。

2、控制台輸出

默認的日誌配置就是將日誌資訊顯示到控制台,默認情況下,將會顯示INFO級別以上的日誌資訊。你還可以通過使用--debug標誌啟動debug模式。

$ java -jar myapp.jar --debug

使用IDEA操作可以編輯Program arguments:--debug。

在application.properties中配置debug=true同樣也可以將日誌級別調整到DEBUG。

3、文件輸出

默認情況下,SpringBoot的日誌只會輸出到控制台,如果你還想輸出到文件中,你需要配置logging.file.name和logging.file.path兩個屬性。

下面這個表格展示如何組合使用logging.*來達到理想的效果:

logging.file.name logging.file.path Example Description
(none) (none) 只會輸出到控制台
指定文件 (none) my.log 寫入指定的日誌文件在當前項目目錄下
(none) 指定目錄 log 在當前項目下的log目錄,寫入spring.log文件

日誌文件達到10 MB時會觸發滾動策略【切分】,默認情況下會記錄INFO以上級別的資訊。 可以使用logging.file.max-size屬性更改大小限制。 除非已設置logging.file.max-history屬性,否則默認情況下將保留最近7天的輪轉日誌文件。 可以使用logging.file.total-size-cap限制日誌歸檔文件的總大小。 當日誌歸檔的總大小超過該閾值時,將刪除備份。 要在應用程式啟動時強制清除日誌存檔,請使用logging.file.clean-history-on-start屬性。

4、日誌級別

可以使用logging.level設置所有受支援的日誌記錄器的級別。

logging.level.root=warn
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error

5、日誌組

使用logging.group能夠將相關的logger組合在一起統一管理日誌級別等配置。使用方法如下:

假設定義了group為tomcat:

logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat

一旦這樣定義之後,就可以僅僅通過一行配置,完成相關三個logger的級別配置:

logging.level.tomcat=TRACE

SpringBoot預定義了兩個開箱即用的日誌組:

Name Loggers
web org.springframework.core.codec, org.springframework.http, org.springframework.web, org.springframework.boot.actuate.endpoint.web, org.springframework.boot.web.servlet.ServletContextInitializerBeans
sql org.springframework.jdbc.core, org.hibernate.SQL, org.jooq.tools.LoggerListener
# pre-defined
logging.level.web=debug
logging.level.sql=debug

6、自定義log配置

由於日誌服務一般都在ApplicationContext創建前就初始化了,它並不是必須通過Spring的配置文件控制。因此通過系統屬性和傳統的Spring Boot外部配置文件依然可以很好的支援日誌控制和管理。

你可以根據你的日誌系統,按照下面表格的定義規則,選擇定義對應的日誌配置:

Logging System Customization
Logback logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging) logging.properties

SpringBoot官方推薦使用帶有-spring的文件名作為配置,如logback-spring.xml而不是logback.xml。

這樣命名的好處在於:因為標準的logback.xml配置文件載入得太早,所以不能在其中使用擴展,需要使用logback-spring.xml。

當然上面是默認的命名規則,如果你想自定義xml的名稱,自定義路徑,可以通過logging.config屬性配置:logging.config=classpath:logging-config.xml

三、logback-spring.xml自定義注意事項

接下來分享一份配置十分詳細的logback.xml配置,參照注釋,應該就能夠掌握xml的定義。

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="10 seconds" debug="false">
    <!-- 日誌級別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果設置為WARN,則低於WARN的資訊都不會輸出 -->
    <!-- scan:當此屬性設置為true時,配置文件如果發生改變,將會被重新載入,默認值為true -->
    <!-- scanPeriod:設置監測配置文件是否有修改的時間間隔,如果沒有給出時間單位,默認單位是毫秒。當scan為true時,此屬性生效。默認的時間間隔為1分鐘。 -->
    <!-- debug:當此屬性設置為true時,將列印出logback內部日誌資訊,實時查看logback運行狀態。默認值為false。 -->
    <contextName>logback</contextName>
    <!-- name的值是變數的名稱,value的值時變數定義的值。通過定義的值會被插入到logger上下文中。定義變數後,可以使「${}」來使用變數。 -->
    <property name="log.path" value="log" />
    <property name="console_log_pattern"
              value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}) - %gray(%msg%n)"/>
    <property name="charset" value="UTF-8"/>
    <!--輸出到控制台-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日誌appender是為開發使用,只配置最底級別,控制台輸出的日誌級別是大於或等於此級別的日誌資訊-->
        <!-- 例如:如果此處配置了INFO級別,則後面其他位置即使配置了DEBUG級別的日誌,也不會被輸出 -->
         <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
             <level>DEBUG</level>
         </filter>
        <encoder>
            <pattern>${console_log_pattern}</pattern>
        </encoder>
    </appender>

    <!--輸出到文件,只記錄INFO級別資訊-->
    <appender name="info_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/roll_info/logback.%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>${console_log_pattern}</pattern>
            <charset>${charset}</charset>
        </encoder>
        <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日誌歸檔路徑以及格式 -->
            <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日誌文件保留天數-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 如果超過10MB就刪除 -->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <maxFileSize>10MB</maxFileSize>
        </triggeringPolicy>
        <!-- 此日誌文件只記錄info級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--輸出到文件,只記錄WARN級別資訊-->
    <appender name="warn_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
    </appender>
    <!--輸出到文件,只記錄ERROR級別資訊-->
    <appender name="error_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
    </appender>

    <!--
    root節點是必選節點,用來指定最基礎的日誌輸出級別,只有一個level屬性
    level:用來設置列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默認是DEBUG
    可以包含零個或多個appender元素。
    -->
    <root level="info">
        <appender-ref ref="console" />
        <appender-ref ref="info_file" />
        <appender-ref ref="warn_file"/>
        <appender-ref ref="error_file"/>
    </root>

    <!--
        <logger>用來設置某一個包或者具體的某一個類的日誌列印級別、以及指定<appender>。
        <logger>僅有一個name屬性,
        一個可選的level和一個可選的additivity屬性。
        name:用來指定受此logger約束的某一個包或者具體的某一個類。
        level:用來設置列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
              如果未設置此屬性,那麼當前logger將會繼承上級的級別。
        additivity:是否向上級logger傳遞列印資訊,默認是true
    -->
    <!-- 使用mybatis的時候,sql語句是debug下才會列印,而這裡我們只配置了info,所以想要查看sql語句的話,有以下兩種操作:
         第一種把<root level="INFO">改成<root level="DEBUG">這樣就會列印sql,不過這樣日誌那邊會出現很多其他消息
         第二種就是單獨給mapper下目錄配置DEBUG模式,程式碼如下,這樣配置sql語句會列印,其他還是正常DEBUG級別:
    -->
    <logger name="com.hyh.logback.web.LogTestController" level="WARN" additivity="false">
        <appender-ref ref="console"/>
        <appender-ref ref="warn_file"/>
        <appender-ref ref="error_file"/>
    </logger>

    <!--    如果多環境開發可以用springProfile -->
    <!--開發環境:列印控制台-->
    <springProfile name="dev">
        <!--可以輸出項目中的debug日誌,包括mybatis的sql日誌-->
        <logger name="com.hyh.logback.web" level="DEBUG">
            <appender-ref ref="console"/>
        </logger>
        <!--
            root節點是必選節點,用來指定最基礎的日誌輸出級別,只有一個level屬性
            level:用來設置列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默認是DEBUG
            可以包含零個或多個appender元素。
        -->
        <root level="INFO">
            <appender-ref ref="console"/>
        </root>
    </springProfile>
</configuration>

最終的效果,會在項目路徑下生成日誌文件:/log/info/log-info-2020-11-01.0.log,並且日誌文件的策略也在xml中定義。

控制台列印資訊,如下圖所示:

配置文件下載

本文內容均為對優秀部落格及官方文檔總結而得,原文地址均已在文中參考閱讀處標註。最後,文中的程式碼及配置文件詳細樣例已經全部上傳至Gitee://gitee.com/tqbx/springboot-samples-learn

參考閱讀