Java日誌記錄框架Logback配置詳解(企業級應用解決方案)

前言

Logback是現在比較流行的一個日誌記錄框架,它的配置比較簡單學習成本相對較低,所以剛剛接觸該框架的朋友不要畏懼,多花點耐心很快就能靈活應用了。本篇博文不會具體介紹Logback搭建過程,如果你是Logback初學者強烈建議閱讀Logback常用配置詳解,它對Logback的配置介紹的非常的詳細,相信你看完這篇博客後會對Logback有一定的瞭解,然後再回頭看下面的內容收穫會更大

YAML配置

# 日誌配置
logging:
  config: classpath:logback.xml

企業級應用常用Logback配置

<?xml version="1.0" encoding="UTF-8" ?>
<!--
    scan:當此屬性設置爲true時,配置文件如果發生改變,將會被重新加載,默認值爲true
    scanPeriod:設置監測配置文件是否有修改的時間間隔,如果沒有給出時間單位默認單位是毫秒,當scan爲true時此屬性生效,默認時間間隔爲1分鐘
    debug:當此屬性設置爲true時,將打印出logback內部日誌信息,實時查看logback運行狀態,默認值爲false
 -->
<configuration scan="true" scanPeriod="3 seconds" debug="false">
    <!-- 這一句的意思是打印所有進入的信息 -->
    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />

    <!--
        appender是<configuration>的子節點,是負責寫日誌的組件
        兩個必要屬性name和class:name指定appender名稱,class指定appender的全限定名
        定義控制檯appender 作用:把日誌輸出到控制檯 class="ch.qos.logback.core.ConsoleAppender"
    -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 對日誌進行格式化 -->
        <encoder>
            <pattern>
                {"timestamp":"%d{yyyy-MM-dd'T'HH:mm:ss.SSS}","thread":"%t","line":"%line","log_level":"%p","class_name":"%C;","msg":"%m"}\n
            </pattern>
        </encoder>
    </appender>

    <!--
        定義滾動記錄文件appender 作用:滾動記錄文件,先將日誌記錄到指定文件,當符合某個條件時,將日誌記錄到其他文件
        RollingFileAppender class="ch.qos.logback.core.rolling.RollingFileAppender"
        參數:
            <append>:如果是true日誌被追加到文件結尾,如果是false清空現存文件,默認是true
            <file>:被寫入的文件名,可以是相對目錄也可以是絕對目錄,如果上級目錄不存在會自動創建,沒有默認值
            <rollingPolicy>:當發生滾動時,決定RollingFileAppender的行爲,涉及文件移動和重命名
            <triggeringPolicy>:告知RollingFileAppender合適激活滾動
            <prudent>:當爲true時不支持FixedWindowRollingPolicy支持TimeBasedRollingPolicy,但是有兩個限制:1不支持也不允許文件壓縮,2不能設置file屬性必須留空
    -->
    <appender name="LOGBACK_ALL_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <append>true</append>
        <file>logs/logback-test-all.log</file>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天滾動一次的日誌 -->
            <FileNamePattern>logs/logback-test.%d{yyyy-MM-dd}.log.zip</FileNamePattern>
            <!-- 每分鐘滾動一次日誌 -->
            <!-- <FileNamePattern>logs/logback-test.%d{yyyy-MM-dd_HH-mm}.log.zip</FileNamePattern> -->
            <!--  只保留30天內的日誌文件 -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>

        <!-- 配置臨界值過濾器 作用:過濾掉低於指定臨界值的日誌,當日志級別等於或高於臨界值時過濾器返回NEUTRAL,當日志級別低於臨界值時,日誌會被拒絕 此處配置爲INFO 即過濾掉日誌級別小於INFO的日誌信息 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>

        <encoder>
            <pattern>
                {"timestamp":"%d{yyyy-MM-dd'T'HH:mm:ss.SSS}","thread":"%t","line":"%line","log_level":"%p","class_name":"%C;","msg":"%m%n", "caller":"%caller{1}"}
            </pattern>
        </encoder>
    </appender>

    <!--
        定義滾動記錄文件appender 作用:滾動記錄文件,先將日誌記錄到指定文件,當符合某個條件時,將日誌記錄到其他文件
        RollingFileAppender class="ch.qos.logback.core.rolling.RollingFileAppender"
        參數:
            <append>:如果是true日誌被追加到文件結尾,如果是false清空現存文件,默認是true
            <file>:被寫入的文件名,可以是相對目錄也可以是絕對目錄,如果上級目錄不存在會自動創建,沒有默認值
            <rollingPolicy>:當發生滾動時,決定RollingFileAppender的行爲,涉及文件移動和重命名
            <triggeringPolicy>:告知RollingFileAppender合適激活滾動
            <prudent>:當爲true時不支持FixedWindowRollingPolicy支持TimeBasedRollingPolicy,但是有兩個限制:1不支持也不允許文件壓縮,2不能設置file屬性必須留空
     -->
    <appender name="LOGBACK_ERROR_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <append>true</append>
        <file>logs/logback-test-error.log</file>
        <!--
            定義滾動策略 作用:根據固定窗口算法重命名文件的滾動策略 class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy
            <fileNamePattern>:表示當觸發了回滾策略後,按這個文件命名規則生成歸檔文件,命名規則中的%i表示在maxIndex和minIndex之間的一個整數值
            <minIndex>:最小索引值
            <maxIndex>:最大索引值
         -->
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <fileNamePattern>logs/logback-test-error.log.%i</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>20</maxIndex>
        </rollingPolicy>

        <!-- 定義按文件大小觸發滾動策略triggeringPolicy 作用:查看當前活動文件的大小,如果超過指定大小會告知RollingFileAppender觸發當前活動文件滾動 只有一個參數 maxSize 這是活動文件的大小,默認值是10MB -->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <maxFileSize>50MB</maxFileSize>
        </triggeringPolicy>

        <!--
            配置日誌級別過濾器 作用:根據日誌級別進行過濾,如果日誌級別等於配置級別過濾器會根據onMath和onMismatch接收或拒絕日誌
            參數:
                <level>:設置過濾級別
                <onMatch>:用於配置符合過濾條件的操作
                <onMismatch>:用於配置不符合過濾條件的操作
                此處配置爲只接收ERROR日誌級別信息
        -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>

        <encoder>
            <pattern>
                {"timestamp":"%d{yyyy-MM-dd'T'HH:mm:ss.SSS}","thread":"%t","line":"%line","log_level":"%p","class_name":"%C;","msg":"%m%n", "caller":"%caller{1}"}
            </pattern>
        </encoder>
    </appender>

    <!--
        logger用來設置某一個包的日誌打印級別,以及指定<appender>
        <loger> 僅有一個name屬性,一個可選的level和一個可選的addtivity屬性
                name:用來指定受此loger約束的某一個包或者具體的某一個類
                level:用來設置打印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
                addtivity:是否向上級loger傳遞打印信息。默認是true,會將信息輸入到root配置指定的地方,可以包含多個appender-ref,標識這個appender會添加到這個logger
    -->
    <logger name="com.roberto" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="LOGBACK_ALL_LOG" />
        <appender-ref ref="LOGBACK_ERROR_LOG" />
    </logger>

    <!-- 將root的打印級別設置爲"INFO",指定了名字爲"FILE","STDOUT"的appender -->
    <root>
        <level value="INFO" />
        <appender-ref ref="STDOUT" />
        <appender-ref ref="LOGBACK_ALL_LOG" />
        <appender-ref ref="LOGBACK_ERROR_LOG" />
    </root>
</configuration>

以上配置部分涵蓋了大部分日誌記錄的需求,如控制檯輸出日誌、文件記錄日誌、日誌輸出格式化、按文件大小滾動日誌、按日期滾動日誌、日誌級別過濾等等,在實際應用中只需對配置進行適當的修改即可。以上配置註釋部分可以幫助你解決百分90的疑惑,接下來我以上訴配置爲基準,運行程序進行簡單解釋說明

企業級應用常用Logback配置講解

  • com.roberto包下測試

    package com.roberto;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class LogbackTest {
      private static Logger LOGGER = LoggerFactory.getLogger(LogbackTest.class);
    
      public static void main(String[] args) {
          LOGGER.debug("=======DEBUG=======");
          LOGGER.info("========INFO=======");
          LOGGER.warn("========WARN=======");
          LOGGER.error("=======ERROR=======");
      }
    }

    以上訴配置爲基準新建Logback測試類 觀察日誌輸出情況 切記包名爲com.roberto

    • 控制檯輸出
    {"timestamp":"2018-08-17T10:42:11.089","thread":"main","line":"28","log_level":"DEBUG","class_name":"com.roberto.LogbackTest;","msg":"=======DEBUG======="}
    {"timestamp":"2018-08-17T10:42:11.094","thread":"main","line":"29","log_level":"INFO","class_name":"com.roberto.LogbackTest;","msg":"========INFO======="}
    {"timestamp":"2018-08-17T10:42:11.095","thread":"main","line":"30","log_level":"WARN","class_name":"com.roberto.LogbackTest;","msg":"========WARN======="}
    {"timestamp":"2018-08-17T10:42:11.095","thread":"main","line":"31","log_level":"ERROR","class_name":"com.roberto.LogbackTest;","msg":"=======ERROR======="}
    <logger name="com.roberto" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="LOGBACK_ALL_LOG" />
        <appender-ref ref="LOGBACK_ERROR_LOG" />
    </logger>

    控制檯打印以上內容是因爲這裏配置了包名爲com.robertoDEBUG信息輸出到控制檯

    • logback-test-all.log內容
    {"timestamp":"2018-08-17T10:42:11.094","thread":"main","line":"29","log_level":"INFO","class_name":"com.roberto.LogbackTest;","msg":"========INFO=======", "caller":"Caller+0     at com.roberto.LogbackTest.main(LogbackTest.java:29)"}
    {"timestamp":"2018-08-17T10:42:11.095","thread":"main","line":"30","log_level":"WARN","class_name":"com.roberto.LogbackTest;","msg":"========WARN=======", "caller":"Caller+0     at com.roberto.LogbackTest.main(LogbackTest.java:30)"}
    {"timestamp":"2018-08-17T10:42:11.095","thread":"main","line":"31","log_level":"ERROR","class_name":"com.roberto.LogbackTest;","msg":"=======ERROR=======", "caller":"Caller+0     at com.roberto.LogbackTest.main(LogbackTest.java:31)"}
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>INFO</level>
    </filter>

    雖然配置com.robertoDEBUG級別信息輸出到logback-test-all.log,但是由於LOGBACK_ALL_LOGappender中配置了過濾器,過濾掉了INFO級別以下的信息,所以logback-test-all.log信息如上

    • logback-test-error.log內容
    {"timestamp":"2018-08-17T10:42:11.095","thread":"main","line":"31","log_level":"ERROR","class_name":"com.roberto.LogbackTest;","msg":"=======ERROR=======", "caller":"Caller+0     at com.roberto.LogbackTest.main(LogbackTest.java:31)"}
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>ERROR</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>

    雖然配置com.robertoDEBUG級別信息輸出到logback-test-error.log,但是由於LOGBACK_ERROR_LOGappender中配置了過濾器,只輸出ERROR級別信息,所以logback-test-error.log打印信息如上

  • 在非com.roberto包下測試

    package com.dreamt;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class LogbackTest {
      private static Logger LOGGER = LoggerFactory.getLogger(LogbackTest.class);
    
      public static void main(String[] args) {
          LOGGER.debug("=======DEBUG=======");
          LOGGER.info("========INFO=======");
          LOGGER.warn("========WARN=======");
          LOGGER.error("=======ERROR=======");
      }
    }

    注意此處包名不爲com.roberto,觀察日誌輸出情況

    • 控制檯輸出
    {"timestamp":"2018-08-17T10:53:22.669","thread":"main","line":"29","log_level":"INFO","class_name":"com.dreamt.LogbackTest;","msg":"========INFO======="}
    {"timestamp":"2018-08-17T10:53:22.678","thread":"main","line":"30","log_level":"WARN","class_name":"com.dreamt.LogbackTest;","msg":"========WARN======="}
    {"timestamp":"2018-08-17T10:53:22.679","thread":"main","line":"31","log_level":"ERROR","class_name":"com.dreamt.LogbackTest;","msg":"=======ERROR======="}
    • logback-test-all.log內容
    {"timestamp":"2018-08-17T10:53:22.669","thread":"main","line":"29","log_level":"INFO","class_name":"com.dreamt.LogbackTest;","msg":"========INFO=======", "caller":"Caller+0     at com.dreamt.LogbackTest.main(LogbackTest.java:29)"}
    {"timestamp":"2018-08-17T10:53:22.678","thread":"main","line":"30","log_level":"WARN","class_name":"com.dreamt.LogbackTest;","msg":"========WARN=======", "caller":"Caller+0     at com.dreamt.LogbackTest.main(LogbackTest.java:30)"}
    {"timestamp":"2018-08-17T10:53:22.679","thread":"main","line":"31","log_level":"ERROR","class_name":"com.dreamt.LogbackTest;","msg":"=======ERROR=======", "caller":"Caller+0     at com.dreamt.LogbackTest.main(LogbackTest.java:31)"}
    • logback-test-error.log內容
    {"timestamp":"2018-08-17T10:53:22.679","thread":"main","line":"31","log_level":"ERROR","class_name":"com.dreamt.LogbackTest;","msg":"=======ERROR=======", "caller":"Caller+0     at com.dreamt.LogbackTest.main(LogbackTest.java:31)"}
    • 以上輸出是由於配置文件如下
    <root>
        <level value="INFO" />
        <appender-ref ref="STDOUT" />
        <appender-ref ref="LOGBACK_ALL_LOG" />
        <appender-ref ref="LOGBACK_ERROR_LOG" />
    </root>

關於滾動日誌這裏就不做測試,你們可以自己寫個循環輸出日誌進行測試,上面配置註釋的非常清楚,只要你們肯動手肯定能實驗成功的,以上部分純屬個人拙見,如有誤解歡迎大家指正,謝謝~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章