1、配置文件的基本結(jié)構(gòu)
????????以<configuration>開頭,后面有零個或多個<appender>元素,有零個或多個<logger>元素,有最多一個<root>元素。

? ??????Logback默認(rèn)配置的步驟
? ???????(1).?嘗試在?classpath?下查找文件?logback-test.xml;
???????? (2).?如果文件不存在,則查找文件?logback.xml;
???????? (3).?如果兩個文件都不存在,logback?用?BasicConfigurator?自動對自己進行配置,這會導(dǎo)致記錄輸出到控制臺。
????????BasicConfigurator 創(chuàng)建的是一個最小化配置。最小化配置由一個關(guān)聯(lián)到根?logger?的ConsoleAppender?組成。輸出用模式為%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n?的?PatternLayoutEncoder?進行格式化。root logger?默認(rèn)級別是?DEBUG。
2、根節(jié)點<configuration>包含的屬性
scan:? 當(dāng)此屬性設(shè)置為true時,配置文件如果發(fā)生改變,將會被重新加載,默認(rèn)值為true。
scanPeriod:? 設(shè)置監(jiān)測配置文件是否有修改的時間間隔,如果沒有給出時間單位,默認(rèn)單位是毫秒。當(dāng)scan為true時,此屬性生效。默認(rèn)的時間間隔為1分鐘。
debug:? 當(dāng)此屬性設(shè)置為true時,將打印出logback內(nèi)部日志信息,實時查看logback運行狀態(tài)。默認(rèn)值為false。
<configuration scan="true" scanPeriod="60 seconds" debug="false">
????????<!-- 其他配置省略-->
</configuration>
3、appender
? ? ? Appender主要用于指定日志輸出的目的地,目的地可以是控制臺、文件、遠(yuǎn)程套接字服務(wù)器、?MySQL、?PostreSQL、?Oracle和其他數(shù)據(jù)庫、?JMS和遠(yuǎn)程UNIX Syslog守護進程等。并可以指定日志文件的一些屬性。主要屬性 :
(1)<File>?指定日志輸出的目的地
(2)RollingFileAppender 包含的組件
?<rollingPolicy>?負(fù)責(zé)日志輪轉(zhuǎn)動作,可移動文件以及對文件改名
<triggeringPolicy>負(fù)責(zé)日志輪轉(zhuǎn)的時機
(3)<layout>?負(fù)責(zé)把事件轉(zhuǎn)換成字符串,格式化的日志信息的輸出。日志具體格式參見:http://www.itdecent.cn/p/75f7ace1bb96
(4)<filter> 可結(jié)合過濾器使用,只打印過濾器中級別的日志。
具體解析如下:
常用的appender

RollingPolicy

rollingPolicy 負(fù)責(zé)日志輪轉(zhuǎn)動作,可移動文件以及對文件改名
TimeBasedRoolingPolicy:時間滾動策略,可以基于時間滾動按時間生成日志。即負(fù)責(zé)輪轉(zhuǎn)的行為,也負(fù)責(zé)觸發(fā)輪轉(zhuǎn) ,同時實現(xiàn)了RollingPolicy 和 TriggeringPolicy 接口。屬性:
(1)? fileNamePattern :定義了輪轉(zhuǎn)時的屬性名,強制屬性 。?格式如:${LOG_HOME}/${LOGERROR_NAME}.%d{yyyy-MM-dd}.%i.log(每天輪轉(zhuǎn)(晚上零點))
(2)??maxHistory:保存歷史記錄的天數(shù)
(3)??totalSizeCap:歸檔文件總大小?
(4)??cleanHistoryOnStart :boolean類型,如果設(shè)置為 true,那么在 appender 啟動的時候,歸檔文件將會被刪除。默認(rèn)的值為 false。歸檔文件的刪除通常在輪轉(zhuǎn)期間執(zhí)行。但是,有些應(yīng)用的存活時間可能等不到輪轉(zhuǎn)觸發(fā)。對于這種短期應(yīng)用,可以通過設(shè)置該屬性為 true,在 appender 啟動的時候執(zhí)行刪除操作。?
(5)??多個JVM寫同一個日志文件的配置,需要開啟(節(jié)儉)prudent模式:<prudent>true</prudent>。TimeBasedRollingPolicy支持文件自動壓縮。如果?fileNamePattern以?.gz?或者?.zip結(jié)尾,將會啟動這個特性。
SizeAndTimeBasedRollingPolicy :基于大小和時間的滾動策略 。屬性:?maxFileSize(單個文件最大值)、maxHistory、?totalSizeCap。注意: %d 、 %i 這兩個占位符都是強制要求的。在當(dāng)前時間還沒有到達(dá)周期輪轉(zhuǎn)之前,日志文件達(dá)到了maxFileSize?指定的大小,會進行歸檔,遞增索引從 0 開始。
注:在此之前使用的SizeAndTimeBasedFNATP,只定義文件大小maxFileSize?,結(jié)合TimeBasedRollingPolicy? 中定義的時間maxHistory,來達(dá)到基于大小和時間的滾動,如下圖(基于大小和時間的滾動策略 -舊版配置)。目前,SizeAndTimeBasedFNATP is deprecated. Use SizeAndTimeBasedRollingPolicy instead .?
https://stackoverflow.com/questions/54033579/moving-to-sizeandtimebasedrollingpolicy-from-timebasedrollingpolicy-to-rollover
FixedWindowRollingPolicy :基于固定窗口的滾動策略 。這個策略的出現(xiàn),我個人猜測是因為需要日志文件保持為某個特定的數(shù)量,防止?jié)L動測策略導(dǎo)致過多的日志文件出現(xiàn)。這個策略出現(xiàn)得配合triggeringPolicy,給一個什么時候日志滾動一次的控制,這部分是跟上面兩種策略所不一樣的地方。屬性:minIndex(窗口索引最小值)、maxIndex(窗口索引最大值)、fileNamePattern (必須包含%i)


TriggeringPolicy

TriggeringPolicy 用于通知RollingFileAppender?何時輪轉(zhuǎn)。TriggeringPolicy接口僅僅只包含了一個方法。isTriggeringEvent() 接收當(dāng)前活動的文件以及當(dāng)前的日志事件作為參數(shù)。基于這些參數(shù),通過具體的實現(xiàn)來決定輪轉(zhuǎn)是不是應(yīng)該發(fā)生。
TimeBasedRollingPolicy 是使用最廣泛的觸發(fā)策略。也可以用作輪轉(zhuǎn)策略來使用。
SizeBasedTriggeringPolicy 觀察當(dāng)前活動文件的大小,如果已經(jīng)大于了指定的值,它會給 RollingFileAppender?發(fā)一個信號觸發(fā)對當(dāng)前活動文件的輪轉(zhuǎn)。只接收 maxFileSize?這一個參數(shù),它的默認(rèn)值是 10 MB。?
TimeBasedRollingPolicy和SizeBasedTriggeringPolicy沖突,不能用這兩個一起來控制時間和文件大小,詳見:https://blog.csdn.net/wujianmin577/article/details/68922545

一般的組合:
TimeBasedRoolingPolicy?
TimeBasedRoolingPolicy+SizeAndTimeBasedFNATP<=>SizeAndTimeBasedRollingPolicy?
TimeBasedRollingPolicy + SizeBasedTriggeringPolicy? ?沖突FixedWindowRollingPolicy?單獨不能使用
FixedWindowRollingPolicy +SizeBasedTriggeringPolicy??
filter
1)?LevelFilter 級別過濾器
根據(jù)日志級別進行過濾。當(dāng)檢測到當(dāng)前日志的打印級別與當(dāng)前過濾器配置的一樣時,如logger.info(msg),同時過濾器設(shè)置為<level>info</level>,過濾器會根據(jù)onMath 和 onMismatch接收或拒絕日志.
子節(jié)點:
<level>:設(shè)置過濾級別
<onMatch>:用于配置符合過濾條件的操作
<onMismatch>:用于配置不符合過濾條件的操作
例:將過濾器的日志級別配置為INFO,所有INFO級別的日志交給appender處理,非INFO級別的日志,被過濾掉。

注意:LevelFilter 僅僅配置 level 是無法真正起作用的。由于沒有配置 onMatch 和 onMismatch 屬性,所以相當(dāng)于這個過濾器是無用的,導(dǎo)致 level配置以上級別的日志都記錄了。


可以看到,_info.log 中包含了 INFO、WARN 和 ERROR 三個級別的日志,不符合我們的預(yù)期;

2) ThresholdFilter 臨界值過濾器
過濾掉低于指定臨界值的日志。當(dāng)日志級別等于或高于臨界值時,過濾器返回NEUTRAL;當(dāng)日志級別低于臨界值時,日志會被拒絕。
例:error.log 包含了 WARN 和 ERROR 兩個級別的日志。


3) EvaluatorFilter 求值過濾器
自定義條件,隨意控制輸出。需要額外的兩個JAR包,commons-compiler.jar和janino.jar
<!-- https://mvnrepository.com/artifact/org.codehaus.janino/janino -->
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.codehaus.janino</groupId>
? ? ? ? ? ? <artifactId>janino</artifactId>
? ? ? ? ? ? <version>3.1.0</version>
? ? ? ? </dependency>
子節(jié)點:
<evaluator>?: 鑒別器,常用的鑒別器是JaninoEventEvaluato,也是默認(rèn)的鑒別器,它以任意的java布爾值表達(dá)式作為求值條件,求值條件在配置文件解釋過成功被動態(tài)編譯,布爾值表達(dá)式返回true就表示符合過濾條件
<expression>: 用于配置求值條件。求值表達(dá)式作用于當(dāng)前日志,logback向求值表達(dá)式暴露日志的各種字段:

<onMatch>:用于配置符合過濾條件的操作
<onMismatch>:用于配置不符合過濾條件的操作
例:過濾掉所有日志消息中不包含“billing”字符串的日志。

例:記錄帶有 time 標(biāo)記的日志



4、Logger、ROOT
(1)設(shè)置logger
用來設(shè)置某一個包或者具體的某一個類的日志打印級別、以及指定。僅有一個name屬性,一個可選的level和一個可選的addtivity屬性。
name:用來指定受此loger約束的某一個包或者具體的某一個類。即打印該包下的日志。
level:用來設(shè)置打印級別(日志級別),大小寫無關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,還有一個特俗值INHERITED或者同義詞NULL,代表強制執(zhí)行上級的級別。如果未設(shè)置此屬性,那么當(dāng)前l(fā)oger將會繼承上級的級別。
addtivity:是否向上級loger傳遞打印信息。默認(rèn)是true。設(shè)置為true,將該logger的name定義的包以及打印日志的級別level等都傳給root,交由root再打印,而該logger是否打印取決于是否配置了appender。(相當(dāng)于子類重寫了父類的方法,level由子類決定)
可以包含零個或多個元素,標(biāo)識這個appender將會添加到這個loger。
設(shè)置root
也是元素,但是它是根loger。只有一個level屬性,應(yīng)為已經(jīng)被命名為"root".
level:用來設(shè)置打印級別,大小寫無關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能設(shè)置為INHERITED或者同義詞NULL。默認(rèn)是DEBUG。
root可以理解為一個根節(jié)點,而其他的logger都可以看做root的子節(jié)點
所以默認(rèn)root配置的appender屬性logger都是使用的,如果不想使用可以logger定義時增加屬性additivity="false"
ps:<logger?name="net.jy.redis.controller.logback.LogbackController"?level="warn"?additivity="false"><appender-ref?ref="stdout"/></logger>
因為上述關(guān)系,在class類使用getLogger("name/class")引入logger時,如果"name/class"未在配置文件中找到,則默認(rèn)使用root配置
如果匹配到"name/class",則使用匹配到的appender配置的輸出,同時可自行選擇是否關(guān)閉root配置的appender輸出
可以包含零個或多個元素,標(biāo)識這個appender將會添加到這個loger。


<logger name="logback" />將控制logback包下的所有類的日志的打印,但是并沒用設(shè)置打印級別,所以繼承他的上級<root>的日志級別“DEBUG”;
沒有設(shè)置addtivity,默認(rèn)為true,將此loger的打印信息向上級傳遞;
沒有設(shè)置appender,此loger本身不打印任何信息。
<root level="DEBUG">將root的打印級別設(shè)置為“DEBUG”,指定了名字為“STDOUT”的appender。
當(dāng)執(zhí)行l(wèi)ogback.LogbackDemo類的main方法時,因為LogbackDemo 在包logback中,所以首先執(zhí)行<logger name="logback" />,將級別為“DEBUG”及大于“DEBUG”的日志信息傳遞給root,本身并不打??;root接到下級傳遞的信息,交給已經(jīng)配置好的名為“STDOUT”的appender處理,“STDOUT”appender將信息打印到控制臺;


<logger name="logback" />將控制logback包下的所有類的日志的打印,但是并沒用設(shè)置打印級別,所以繼承他的上級<root>的日志級別“DEBUG”;
沒有設(shè)置addtivity,默認(rèn)為true,將此loger的打印信息向上級傳遞;
沒有設(shè)置appender,此loger本身不打印任何信息。
<logger name="logback.LogbackDemo" level="INFO" additivity="false">控制logback.LogbackDemo類的日志打印,打印級別為“INFO”;
additivity屬性為false,表示此loger的打印信息不再向上級傳遞,
指定了名字為“STDOUT”的appender,
<root level="DEBUG">將root的打印級別設(shè)置為“DEBUG”,指定了名字為“STDOUT”的appender。
當(dāng)執(zhí)行l(wèi)ogback.LogbackDemo類的main方法時,先執(zhí)行<logger name="logback.LogbackDemo" level="INFO" additivity="false">,將級別為“INFO”及大于“INFO”的日志信息交給此loger指定的名為“STDOUT”的appender處理,在控制臺中打出日志,不再向次loger的上級 <logger name="logback"/> 傳遞打印信息;
<logger name="logback"/>未接到任何打印信息,當(dāng)然也不會給它的上級root傳遞任何打印信息;

如果將<logger name="logback.LogbackDemo" level="INFO" additivity="false">修改為 <logger name="logback.LogbackDemo" level="INFO" additivity="true">那打印結(jié)果將是什么呢?
沒錯,日志打印了兩次,想必大家都知道原因了,因為打印信息向上級傳遞,logger本身打印一次,root接到后又打印一次。
注意,雖然root中l(wèi)evel為debug,但是logger相當(dāng)于子類重寫父類方法,以logger中的level為準(zhǔn),只打印info日志,不打印debug日志。
