logback解析——Appender

門門門門門發表於2017-12-20

在SSM框架搭建Java Web的過程中,需要去做日誌處理。在配置logback的時候遇到了不少問題,因此而去深入地瞭解了一下logback。除了看了很多部落格的介紹之外,還去看了一下logback的官方文件,看完之後需要去記錄一下所見所得。

首先我們來介紹一個Appender的組成

Appender的類圖如下:

image.png

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>
複製程式碼

相關文章