SpringBoot應用自定義logback日誌
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訪問日誌功能。
官網配置文件地址:https://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
負責把事件轉換成字串,格式化的日誌資訊的輸出。
配置介紹
配置檔案的基本結構:以
預設配置的步驟
- 嘗試在 classpath下查詢檔案logback-test.xml;
- 如果檔案不存在,則查詢檔案logback.xml;
- 如果兩個檔案都不存在,logback用BasicConfigurator自動對自己進行配置,這會導致記錄輸出到控制檯。
```
<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種方式:
- classpath下存在logback-spring.xml
- classpath下有logback.xml
- 配置檔案中通過配置項指定檔案:
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 配置檔案中的
```
<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的配置生效了。
讀取配置檔案配置
本文通過讀取配置檔案中的配置修改輸出的日誌檔名來演示。
- 配置檔案中新增配置項
- logback-spring.xml中新增配置內容如下:
<springProperty scope="context" name="logFileName" source="log.file.name"
defaultValue="output"/>
- scope: 使用範圍
- name: 變數名
- source: 讀取的配置項名
-
defaultValue: 預設名稱
-
通過${....}使用配置
- 結果,成功修改了輸出的日誌檔名
文章程式碼地址:https://github.com/alvinlkk/springboot-demo/tree/master/springboot-log-logback
總結
本文講解了通過自定義logback增強日誌的輸出,希望對大家有幫助。
參考
https://logback.qos.ch/documentation.html
https://blog.csdn.net/CSDN2497242041/article/details/122596582
https://www.cnblogs.com/warking/p/5710303.html
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging
https://blog.csdn.net/RegretLi/article/details/119010356
- Java7到Java17, Switch語句進化史
- 樂觀鎖思想在JAVA中的實現——CAS
- 一步步帶你設計MySQL索引資料結構
- 我總結了寫出高質量程式碼的12條建議
- 工作這麼多年,我總結的資料傳輸物件 (DTO) 的最佳實踐
- Spring專案中用了這種解耦模式,經理對我刮目相看
- 大資料HDFS憑啥能存下百億資料?
- 5個介面效能提升的通用技巧
- 你的哪些SQL慢?看看MySQL慢查詢日誌吧
- 90%的Java開發人員都會犯的5個錯誤
- 喪心病狂,竟有Thread.sleep(0)這種寫法?
- 為什麼更推薦使用組合而非繼承關係?
- 一個30歲程式設計師的覺醒和進擊
- 推薦8個提高工作效率的IntelliJ外掛
- 公司的這種打包啟動方式,我簡直驚呆了
- 告別醜陋判空,一個Optional類搞定
- 你不知道的Map家族中的那些冷門容器
- SpringBoot 2.x整合Log4j2日誌
- SpringBoot應用自定義logback日誌
- 你確定懂了Java中的序列化機制嗎