SpringBoot應用自定義logback日誌

語言: CN / TW / HK

theme: cyanosis

持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第7天,點擊查看活動詳情

概述

默認情況下,SpringBoot內部使用logback作為系統日誌實現的框架,將日誌輸出到控制枱,不會寫到日誌文件。如果在application.properties或application.yml配置,這樣只能配置簡單的場景,保存路徑、日誌格式等。複雜的場景(區分 info 和 error 的日誌、每天產生一個日誌文件等)滿足不了,只能自定義配置文件logback-spring.xml或者logback.xml。本篇文章主要講解下如何自定義logabck.xml以及對logback文件中配置做一個詳解。

logback配置詳解

首先我們先了解下logback。

logback 主要分為三個模塊:

  • logback-core:是其他兩個模塊的基礎模塊
  • logback-classic:是對 core 模塊的擴展,相當於 log4j 的改良版。classic 模塊實現了 Slf4j 的 API 因此可以便於和其他日誌框架直接切換
  • logback-access:與Servlet容器集成,以提供http訪問日誌功能。

官網配置文檔地址:http://logback.qos.ch/manual/configuration.html

配置內容概念介紹

Logger Context

LoggerContext負責製造logger,也負責以樹結構排列各logger。其他所有logger也通過org.slf4j.LoggerFactory 類的靜態方法getLogger取得。 getLogger方法以 logger名稱為參數。

Logger

Logger作為日誌的記錄器,把它關聯到應用的對應的context上後,主要用於存放日誌對象,也可以定義日誌類型、級別。

Appender

Appender主要用於指定日誌輸出的目的地,目的地可以是控制枱、文件、遠程套接字服務器、 MySQL、PostreSQL、 Oracle和其他數據庫、 JMS和遠程UNIX Syslog守護進程等。

Layout

負責把事件轉換成字符串,格式化的日誌信息的輸出。

配置介紹

配置文件的基本結構:以開頭,後面有零個或多個元素,有零個或多個元素,有最多一個元素。

默認配置的步驟

  1. 嘗試在 classpath下查找文件logback-test.xml;
  2. 如果文件不存在,則查找文件logback.xml;
  3. 如果兩個文件都不存在,logback用BasicConfigurator自動對自己進行配置,這會導致記錄輸出到控制枱。

```


${CONTEXT_NAME} ${CUSTOM_LOG_PATTERN} UTF-8 log/testC.%d{yyyy-MM-dd}.%i.log 30 100MB WARN ACCEPT DENY ${CUSTOM_LOG_PATTERN} UTF-8

<appender name="log_file"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 被寫入的文件名,可以是相對目錄,也可以是絕對目錄,如果上級目錄不存在會自動創建,沒有默認值。 -->
    <file>${logs.dir}/logback-test.log</file>
    <!-- 按照固定窗口模式生成日誌文件,當文件大於20MB時,生成新的日誌文件。窗口大小是1到3,當保存了3個歸檔文件後,將覆蓋最早的日誌 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
        <!-- 必須包含“%i”例如,假設最小值和最大值分別為1和2,命名模式為 mylog%i.log,會產生歸檔文件mylog1.log和mylog2.log。還可以指定文件壓縮選項,例如,mylog%i.log.gz 
            或者 沒有log%i.log.zip -->
        <FileNamePattern>${logs.dir}/logback-test.%i.log</FileNamePattern>
        <!-- 窗口索引最小值 -->
        <minIndex>1</minIndex>
        <!-- 窗口索引最大值 -->
        <maxIndex>3</maxIndex>
    </rollingPolicy>
    <!-- 日誌級別過濾器 -->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <!-- 日誌級別過濾器 -->
        <level>INFO</level>
        <!-- 符合要求的日誌級別,過濾,ACCEPT:接受 -->
        <onMatch>ACCEPT</onMatch>
        <!-- 不符合要求的日誌級別,過濾,DENY:拒絕 -->
        <onMismatch>DENY</onMismatch>
    </filter>
    <!-- 激活滾動的條件。 -->
    <triggeringPolicy
        class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <!-- 活動文件的大小,默認值是10MB -->
        <maxFileSize>30MB</maxFileSize>
    </triggeringPolicy>
    <!-- 對記錄事件進行格式化。 -->
    <encoder>
        <pattern>${CUSTOM_LOG_PATTERN}</pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>

<!-- 異步輸出 -->
<appender name="ASYNC_logback" class="ch.qos.logback.classic.AsyncAppender">
    <!-- 不丟失日誌.默認的,如果隊列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日誌 -->
    <!-- <discardingThreshold>0</discardingThreshold> -->
    <!-- 更改默認的隊列的深度,該值會影響性能.默認值為256 -->
    <!-- <queueSize>256</queueSize> -->
    <!-- 添加附加的appender,最多隻能添加一個 -->
    <appender-ref ref="log_file" />
</appender>
<!-- 指定包輸出路徑 -->
<!-- 用來設置某一個 包 或者具體的某一個 類 的日誌打印級別、以及指定<appender>, name:用來指定受此logger約束的某一個包或者具體的某一個類。 
    level:用來設置打印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,還有一個特俗值INHERITED或者同義詞NULL,代表強制執行上級的級別。如果未設置此屬性,那麼當前loger將會繼承上級的級別。 
    additivity:是否向上級logger傳遞打印信息。默認是true。(這個logger的上級就是上面的root) <logger>可以包含零個或多個<appender-ref>元素,標識這個appender將會添加到這個logger。 -->
<logger name="org.logback.test" level="DEBUG" additivity="true">
    <appender-ref ref="stdout" />
</logger>
<!-- 特殊的<logger>元素,是根logger。只有一個level屬性,應為已經被命名為"root". level:設置打印級別,大小寫無關:TRACE, 
    DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能設置為INHERITED或者同義詞NULL。默認是DEBUG。 <root>可以包含零個或多個<appender-ref>元素,標識這個appender將會添加到這個loger。 -->
<root>
    <level value="WARN" />
    <!-- if表達式,需要Janino jar -->
    <!-- Janino 2.6.0版本開始,除了janino.jar之外, commons-compiler.jar也需要在類路徑中 -->
    <if condition='property("system_host").contains("dev")'>
        <then>
            <appender-ref ref="stdout" />
        </then>
    </if>
    <appender-ref ref="file" />
</root>

```

SpringBoot中自定義logback

SpringBoot啟用自定義logback有3種方式:

  1. classpath下存在logback-spring.xml
  2. classpath下有logback.xml
  3. 配置文件中通過配置項指定文件:logging.config: ./logback-rule.xml

如果可能,我們建議您為日誌記錄配置使用-spring變體或者通過配置項的方式(例如,logback-spring.xml而不是logback.xml)。如果使用標準配置,Spring不能完全控制日誌初始化。

我們本例使用logback-spring.xml作為配置文件演示。

在 src/main/resources 下創建 logback-spring.xml 文件,分開記錄系統輸出日誌和Error日誌。

```

<!--dev文件路徑:src同級目錄logs,如果上級目錄不存在會自動創建-->
<property name="DEV_FILE_PATH" value="./logs" />
<!-- pro文件路徑 -->
<property name="PRO_FILE_PATH" value="./logs-prod" />

<!-- 控制枱輸出 -->
<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
    </encoder>
</appender>

<!-- 按照每天生成輸出日誌文件 -->
<appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <encoder>
        <!--格式化輸出:%d表示日期,%thread表示線程,%-5level:級別從左顯示五個字符寬度,%logger{36}:logger是class的全名,後面的數字代表限制最長的字符,%msg:日誌消息,%n換行符-->
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
    <!--滾動策略按照時間滾動-->
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!-- rollover daily 文件名稱 -->
        <fileNamePattern>${DEV_FILE_PATH}/output-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
        <!-- each file should be at most 10MB, keep 60 days worth of history, but at most 2GB -->
        <!--單個文件大小-->
        <maxFileSize>10MB</maxFileSize>
        <!--日誌文件保留天數-->
        <maxHistory>60</maxHistory>
        <!--用來指定日誌文件的上限大小,到了這個值就會刪除舊日誌-->a
        <totalSizeCap>2GB</totalSizeCap>
    </rollingPolicy>
</appender>

<!-- 按照每天生成錯誤日誌文件 -->
<appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 此日誌文件只記錄ERROR級別的 -->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>ERROR</level>
    </filter>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
    <!--輸出日誌到src同級目錄logs中的error.log文件中-->
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!--基於大小和時間的輪轉策略,當日志內容超出文件大小限制後,會自動生成一個文件來繼續記錄和重命名-->
        <fileNamePattern>${DEV_FILE_PATH}/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
        <!-- each file should be at most 10MB, keep 60 days worth of history, but at most 2GB -->
        <maxFileSize>10MB</maxFileSize>
        <maxHistory>60</maxHistory>
        <totalSizeCap>2GB</totalSizeCap>
    </rollingPolicy>
</appender>

<root level="INFO">
    <appender-ref ref="consoleAppender" />
    <appender-ref ref="fileAppender" />
    <appender-ref ref="errorAppender" />
</root>

```

java中打印日誌:

``` @SpringBootApplication @Slf4j public class LogbackApp {

public static void main(String[] args) {
    SpringApplication.run(LogbackApp.class, args);

    log.trace("Trace 日誌...");
    log.debug("Debug 日誌...");
    log.info("Info 日誌...");
    log.warn("Warn 日誌...");
    log.error("Error 日誌...");
}

} ```

輸出結果:

\

SpringBoot官方建議使用logback-spring.xml作為logback框架的自定義日誌配置文件,使用logback-spring.xml而不是logback.xml,因為帶-spring後綴的配置文件可以使用一些擴展的功能。

多環境輸出日誌文件

Logback 配置文件中的 節點指令允許您根據配置文件激活參數(active) 選擇性的包含和排查部分配置信息。根據不同環境來定義不同的日誌輸出,在 logback-spring.xml中使用 節點來定義,方法如下:

```

<springProfile name="dev">
    <root level="DEBUG">
        <appender-ref ref="consoleAppender" />
        <appender-ref ref="fileAppender" />
        <appender-ref ref="errorAppender" />
    </root>
</springProfile>

<!--生產環境:輸出到文件-->
<springProfile name="prod">
    <root level="INFO">
        <appender-ref ref="consoleAppender" />
        <appender-ref ref="fileAppender" />
        <appender-ref ref="errorAppender" />
    </root>
</springProfile>

```

配置文件添加配置項:

結果:

打印出了debug日誌,説明dev的配置生效了。

讀取配置文件配置

本文通過讀取配置文件中的配置修改輸出的日誌文件名來演示。

  1. 配置文件中添加配置項

  1. logback-spring.xml中添加配置內容如下:

<springProperty scope="context" name="logFileName" source="log.file.name" defaultValue="output"/>

  • scope: 使用範圍
  • name: 變量名
  • source: 讀取的配置項名
  • defaultValue: 默認名稱

  • 通過${....}使用配置

  1. 結果,成功修改了輸出的日誌文件名

文章代碼地址:http://github.com/alvinlkk/springboot-demo/tree/master/springboot-log-logback

總結

本文講解了通過自定義logback增強日誌的輸出,希望對大家有幫助。

參考

http://logback.qos.ch/documentation.html

http://blog.csdn.net/CSDN2497242041/article/details/122596582

http://www.cnblogs.com/warking/p/5710303.html

http://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging

http://blog.csdn.net/RegretLi/article/details/119010356

http://juejin.cn/post/6844903775631572999#heading-21

http://www.justdojava.com/2020/10/21/java-log/