在SSM框架搭建Java Web的過程中,需要去做日誌處理。在配置logback的時候遇到了不少問題,因此而去深入地瞭解了一下logback。除了看了很多部落格的介紹之外,還去看了一下logback的官方文件,看完之後需要去記錄一下所見所得。
首先我們來介紹一個Appender的組成
Appender的類圖如下:
ConsoleAppender
ConsoleAppender用於控制檯日誌輸出 官方文件給出了一個示例寫法
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
複製程式碼
- <encoder>的作用是將日誌格式化,轉換為位元組陣列,並將轉換後的位元組陣列輸出到OutputStream 在encoder出現之前,主要依靠Layout來處理日誌格式化。
目前,PatternLayoutEncoder唯一真正有用的編碼器。它只是包裝了 PatternLayout大部分工作。 具體詳見https://logback.qos.ch/manual/encoders.html
FileAppender
FileAppender用於將日誌以檔案形式儲存起來 官方文件示例配置如下
<configuration>
<!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
the key "bySecond" into the logger context. This value will be
available to all subsequent configuration elements. -->
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<!-- use the previously created timestamp to create a uniquely
named log file -->
<file>log-${bySecond}.txt</file>
<encoder>
<pattern>%logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
複製程式碼
- <timestamp>可以用這個屬性來記錄這個配置檔案的解析時間(我暫時還想不到有什麼用)
- <file>記錄檔案的地址和檔名
RollingFileAppender
RollingFileAppender是對FileAppender的一個擴充套件。相較於它的父類,它的主要作用是滾動記錄日誌。 RollingFileAppender有兩個重要的子元件:RollingPolicy和 TriggeringPolicy。RollingPolicy決定日誌滾動方式,TriggeringPolicy決定日誌滾動的觸發條件。 (其實RollingPolicy也可以定義滾動的觸發條件)
而RollingPolicy滾動策略包括以下幾種:
TimeBasedRollingPolicy
基於時間的滾動策略。這個可能是最常用的滾動策略。 官方文件示例配置如下
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logFile.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of history capped at 3GB total size -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
複製程式碼
- <fileNamePattern>滾動後的檔名,也包括了滾動時間的選擇。
- <maxHistory>保留的存檔檔案的數量,與上一個fileNamePattern有關。假設定義為6,當fileNamePattern以天為單位時,即儲存6天的日誌;當以月為單位時,即儲存6個月的日誌。舊的日誌以非同步的方式刪除。
- <totalSizeCap>所有的歸檔日誌的大小。當超過限制時,會刪掉舊的歸檔日誌。
SizeAndTimeBasedRollingPolicy
SizeAndTimeBasedRollingPolicy是基於時間和檔案大小的滾動策略 官方文件示例配置如下
<configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.txt</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="ROLLING" />
</root>
</configuration>
複製程式碼
<totalSizeCap>限定的是所有的歸檔日誌檔案,而<maxFileSize>限定的則是單個日誌檔案
FixedWindowRollingPolicy
基於視窗大小的滾動策略。 這個聽起來可能有點難理解,其實說白了就是將歸檔日誌檔案到最大了就寫到下一個檔案裡,而視窗大小就是最多允許多少份日誌檔案。 官方文件示例配置如下
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>tests.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
複製程式碼
- <minIndex>視窗下限。下限一般都是1啦。
- <maxIndex>視窗上限。一般我們用上限就可以了。
SizeBasedTriggeringPolicy
SizeBasedTriggeringPolicy其實是TriggeringPolicy(決定什麼時候滾動),好像目前暫時也只有這麼一個TriggeringPolicy。 主要作用是歸檔日誌檔案到達一定大小之後進行日誌滾動。 根據網上的說法,TimeBasedRollingPolicy和SizeBasedTriggeringPolicy衝突,不能同時使用。
舊版本的logback裡可以在TimeBasedRollingPolicy這個rollingPolicy下配置一個timeBasedFileNamingAndTriggeringPolicy(實現類為SizeAndTimeBasedFNATP)達到同時配置時間和檔案大小的滾動策略;而在新版本里其實使用SizeAndTimeBasedRollingPolicy就可以同時滿足兩個需求了。
附錄:
下面給出一箇舊版本里Appender的配置:
<!-- 日誌檔案輸出 -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${log.base}/${log.moduleName}.log</File><!-- 設定日誌不超過${log.max.size}時的儲存路徑,注意如果 是web專案會儲存到Tomcat的bin目錄 下 -->
<!-- 滾動記錄檔案,先將日誌記錄到指定檔案,當符合某個條件時,將日誌記錄到其他檔案。-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${log.base}/${log.moduleName}_all_%d{yyyy-MM-dd}.%i.log.zip
</FileNamePattern>
<!-- 當天的日誌大小 超過${log.max.size}時,壓縮日誌並儲存 -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${log.max.size}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 日誌輸出的檔案的格式 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{56}.%method:%L -%msg%n</pattern>
</layout>
</appender>
複製程式碼
而新版本里的SizeAndTimeBasedRollingPolicy配置,官方給出的示例如下:
<configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.txt</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="ROLLING" />
</root>
</configuration>
複製程式碼