前言
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.roberto
的DEBUG
信息輸出到控制檯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.roberto
的DEBUG
級別信息輸出到logback-test-all.log
,但是由於LOGBACK_ALL_LOG
的appender
中配置了過濾器,過濾掉了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.roberto
的DEBUG
級別信息輸出到logback-test-error.log
,但是由於LOGBACK_ERROR_LOG
的appender
中配置了過濾器,只輸出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>
關於滾動日誌這裏就不做測試,你們可以自己寫個循環輸出日誌進行測試,上面配置註釋的非常清楚,只要你們肯動手肯定能實驗成功的,以上部分純屬個人拙見,如有誤解歡迎大家指正,謝謝~