目錄
一、初始化配置文件
1、logback 配置文件的初始化順序
2、logback 內部狀態信息
二、配置文件的結構
1、logger?元素
2、root?元素
3、appender?元素
三、配置文件中的變量引用
1、如何定義一個變量
2、為變量設置默認值
3、變量的嵌套
? ? In symbols one observes an advantage in discovery which is greatest when they express the exact nature of a thing briefly and, as it were, picture it; then indeed the labor of thought is wonderfully diminished.
????????—GOTTFRIED WILHELM LEIBNIZ
? ? ? ? 大致意思是:使用符號的最大優勢,就是符號可以非常清晰、簡潔的描繪一個事務的本質,從而可以極大的減少思想勞動的支出。
//我把這段文字貼在這里,因為它闡釋了配置文件的本質
????????Logback 的配置依賴于 Joran 配置框架,這個框架后邊如果有時間我會扒一下源碼后再進行分享,此處,重點探討 Logback 配置文件的相關內容。
一、初始化配置文件
1、logback 配置文件的初始化順序
????????首先讓我們來看一下?logback 嘗試加載配置時所遵循的初始化步驟:
????????(1)查找自定義的?Configurator
????????Logback 會優先加載自定義的配置器(Configurator),所謂自定義配置器,就是實現了?ch.qos.logback.classic.spi.Configurator 接口的類。
????????Logback 中提供了兩個?Configurator 接口的實現類,一個是?DefaultJoranConfigurator(加載logback.xml文件的配置器),另一個是?BasicConfigurator(默認配置器)。
????????(2)實例化 SerializedModelConfigurator 配置器
????????如果在 Logback 沒有找到用戶提供的自定義配置器,logback 將實例化一個 SerializedModelConfigurator。這是一個序列化模型文件的加載器,加載的文件名稱為:"logback-test.scmo"?或 "logback.scmo"。
????????序列化模型文件的配置執行速度更快,并且不需要任何 XML 庫。與 GraalVM 結合使用,可以產生更小的可執行文件,啟動速度更快。這個加載器我在 Logback 的核心包中沒有找到對應的類,所以暫時不深入分析,了解即可。
????????如果找不到序列化配置模型文件,SerializedModelConfigurator 將返回一個執行狀態,要求調用下一個可用的配置器,即創建并調用 DefaultJoranConfigurator 的實例。
????????(3)執行 DefaultJoranConfigurator 配置器(重點步驟)
? ? ? ? 首先,DefaultJoranConfigurator 會嘗試查找?“logback.configurationFile” 系統屬性上指定的文件。如果可以找到該文件,則會讀取并解釋該文件,然后進行配置。
????????如果沒有找到上述文件,DefaultJoranConfigurator 將嘗試在類路徑上查找配置文件 “logback-test.xml” 。如果可以找到該文件,則會讀取并解釋該文件,然后進行配置。
????????如果沒有找到上述文件,配置器將繼續嘗試在類路徑中查找配置文件 “logback.xml” 。如果可以找到該文件,則會讀取并解釋該文件,然后進行配置。
????????如果找不到配置文件,DefaultJoranConfigurator 將返回一個執行狀態,要求調用下一個可用的配置器,即創建并調用 BasicConfigurator 的實例。
? ? ? ? //從這里可以看出,“logback-test.xml” 文件優先于?“logback.xml” 文件生效。
????????(4)執行 BasicConfigurator 配置器(使用默認配置)
????????如果上述配置文件查找均不成功,logback-classic 將使用 BasicConfigurator 進行自身配置,默認配置會使日志定向輸出到控制臺。執行 BasicConfigurator 配置器,是為了在沒有配置文件的情況下,logback 能夠正常使用日志記錄功能。//默認配置的作用
????????//從 logback 配置文件加載過程來看,就是使用了一串配置器鏈(責任鏈模式)
2、logback 內部狀態信息
????????之前在《如何在項目中快速引入Logback日志?》這篇文章中提到過如何打印 logback 的內部狀態信息,?這些信息在對 logback 相關的問題進行診斷時非常有用。文章中,我們使用程序代碼的方式對狀態信息進行打印,除此之外,還可以使用配置文件的方式。
????????使用配置文件,本質上就是在配置文件中配置一個狀態監聽器(StatusListener),如果我們只是想把內部信息打印在控制臺上,那么就可以配置一個?OnConsoleStatusListener,配置信息如下:
<configuration><!-- 建議: 將狀態偵聽器置于配置文件的頂部 --><statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /><!-- ... 配置文件的剩余部分 --></configuration>
????????為什么建議將狀態偵聽器置于配置文件的頂部呢?
????????這是因為,已注冊的狀態偵聽器將僅接收其注冊后的狀態事件。它不會接收之前的消息。因此,最好將狀態偵聽器注冊指令放置在配置文件頂部的其他指令之前。
? ? ? ? 此外,配置 OnConsoleStatusListener 還有一種更簡潔的方式,直接在?<configuration> 標簽中,將 debug 屬性設置為 true 就可以注冊 OnConsoleStatusListener,如下所示:
<configuration debug="true"><!-- ... 配置文件內容部分 --></configuration>
二、配置文件的結構
????????logback 的配置文件非常靈活,且不需要使用 DTD 文件或 XML 模式指定的語法。其配置文件的基本結構可以描述為:<configuration>?元素,包含零個或多個 <appender> 元素,后邊可以跟零個或多個 <logger> 元素,最后最多跟隨一個 <root> 元素。下圖說明了這個基本結構。
????????logback.xml 配置文件的一般格式內容如下:
<configuration debug="true"> <!--configuration 標簽--><!--1、appender 標簽--><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><!--2、logger 標簽--><logger name="self4.Example" level="INFO" additivity="false"><!--注意:當additivity="true"時可能會重復添加--><!--當與root重復添加時,日志會被打印兩次,因為有兩個一樣的appender--><appender-ref ref="STDOUT" /> </logger><!--3、root 標簽--><root level="debug"><appender-ref ref="STDOUT"/></root></configuration>
1、logger?元素
????????顧名思義,<logger> 元素就是用來配置?logger?的標簽,<logger> 標簽只有三個屬性,分別為:name(記錄器限定名),level(日志級別),additivity(是否追加)。此外,<logger> 元素可以包含零個或多個 <appender-ref> 元素;該元素可以將 appender?添加到指定的記錄器中。
????????其配置示例,可以參考上邊 logback.xml 配置文件的一般格式的內容。
????????使用 <logger> 標簽可以分別對不同的?logger?設置不同的?level?級別,如果不設置?<logger> 標簽,那么所有的?logger 都會繼承根 logger 的配置,也就是?<root> 標簽的配置。
????????有關 logger?繼承的詳細內容,我在這篇文章《Logback 日志框架的架構》中有介紹,可做參考。
2、root?元素
????????<root> 元素用來配置根記錄器(root logger),該標簽只支持單一屬性的 level 屬性。
? ? ? ? 因為根記錄器是最頂層的記錄器,所以它沒有可追加屬性(additivity),同時,根記錄器已經被命名為 “ROOT”,因此它也不允許使用名稱屬性(name)。此外,<root> 元素可以包含零個或多個 <appender-ref> 元素;該元素可以將 appender?添加到根記錄器中。
3、appender?元素
????????<appender> 元素用來配置?appender,該標簽有兩個強制屬性 name 和 class。所謂強制就是必須要配置的意思,其中 name 用來指定 appender 的名稱,class 用來指定要實例化的 appender 類的完全限定名稱。
????????<appender> 元素可以包含零個或一個 <layout> 元素、零個或多個 <encoder> 元素以及零個或多個 <filter> 元素。除了這三個公共元素之外,<appender> 元素還可以包含與 appender 類的 JavaBean 屬性相對應的任意數量的元素。//也就是說Appender實例中的一些屬性也可以在配置文件中進行配置
????????下圖說明了<appender> 元素常見的結構。
????????<layout> 元素采用強制的 class 屬性,要求必須指定要實例化的布局類的完全限定名稱。與 <appender> 元素一樣,<layout> 可以包含與布局實例的屬性相對應的其他元素。由于?<layout> 元素經常被配置,所以如果布局類是 PatternLayout,則可以根據默認的類映射規則省略 class 屬性。//指定字符串的打印格式
????????<encoder> 元素也采用強制的 class 屬性,同?<layout> 元素一樣,它也具有默認的映射,如果編碼器類是 PatternLayoutEncoder,則可以按照默認的類映射規則省略 class 屬性。
????????簡要的示例配置內容如下所示:
<configuration><appender name="FILE" class="ch.qos.logback.core.FileAppender"><file>myApp.log</file><encoder><pattern>%date %level [%thread] %logger{10} [%file:%line] -%kvp- %msg%n</pattern></encoder></appender><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%kvp %msg%n</pattern></encoder></appender><root level="debug"><appender-ref ref="FILE" /><appender-ref ref="STDOUT" /></root>
</configuration>
三、配置文件中的變量引用
????????與許多腳本語言一樣,logback 配置文件也支持對變量進行定義和引用。變量可以定義在配置文件的內部,也可以定義在配置文件的外部(不推薦),甚至還可以動態的進行計算和定義。
????????引用一個變量,可以使用 "${name}" 這種格式,"${name}" 會被解釋為對 name 的屬性值的引用。
1、如何定義一個變量
????????由于歷史原因,在配置文件中定義一個變量,logback 1.0.7 版本之前使用? <property> 標簽,logback 1.0.7 及以后的版本中可以使用?<variable> 標簽,當然也可以使用? <property> 標簽(兼容性)。
????????在配置文件中定義變量的內容如下:
<configuration><!--定義一個變量,變量名稱為USER_HOME --><variable name="USER_HOME" value="/home/sebastien" /><appender name="FILE" class="ch.qos.logback.core.FileAppender"><!--引用定義的變量--><file>${USER_HOME}/myApp.log</file><encoder><pattern>%kvp %msg%n</pattern></encoder></appender><root level="debug"><appender-ref ref="FILE" /></root>
</configuration>
????????如果想將變量定義在外部文件中,可以使用如下配置:
<configuration><!--引入外部文件--><variable file="src/main/java/chapters/configuration/variables1.properties" /><appender name="FILE" class="ch.qos.logback.core.FileAppender"><file>${USER_HOME}/myApp.log</file> <!--引入外部文件中的USER_HOME變量值--><encoder><pattern>%kvp %msg%n</pattern></encoder></appender><root level="debug"><appender-ref ref="FILE" /></root>
</configuration>
????????外部文件 variables1.properties 中的內容如下://鍵值對
USER_HOME=/home/sebastien
2、為變量設置默認值
????????在某些情況下,如果變量未被聲明或者它的值為 null 時,則可能希望變量具有默認值。在?logback 配置中,可以使用 " :- "?運算符來指定默認值,比如,名為 name 的變量沒有被定義,那么 "{name:-golden}" 將被解釋為 "golden"。
3、變量的嵌套
????????logback?的配置完全支持變量的嵌套。變量的名稱、默認值和值的定義都可以引用其他變量。
????????變量值的定義可以包含對其他變量的引用,比如:
#定義的變量
USER_HOME=/home/sebastien
fileName=myApp.log#該變量值的定義可以引用其他變量
destination=${USER_HOME}/${fileName}
????????變量名稱的定義也可以包含對其他變量的引用,比如,如果為名為 "userid" 的變量的值為:"swadian",則 "${${userid}.password}" 引用是變量名為 "swadian.password" 的值。
????????變量默認值的定義同樣也可以包含對其他變量的引用,例如,如果變量 "id"?未被分配值,并且變量 "userid" 的值為 "swadian",則表達式 "${id:-${userid}}" 將返回 "swadian"。
? ? ? ? 當然,logback 配置中還有許多值得探討的內容,但因為時間和篇幅有限,我們只探討了一些常用的配置項,其他詳細內容可以點擊此處查閱官方文檔。
????????至此,全文結束。