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訪問日誌功能。
官網配置文檔地址: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
負責把事件轉換成字符串,格式化的日誌信息的輸出。
配置介紹
配置文件的基本結構:以
默認配置的步驟
- 嘗試在 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: 默認名稱
-
通過${....}使用配置
- 結果,成功修改了輸出的日誌文件名
文章代碼地址: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
- 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中的序列化機制嗎