|
logback是java的日志開源組件,是log4j創(chuàng)始人寫的,性能比log4j要好,目前主要分為3個模塊
本篇博客會講解logback的使用、配置詳解、以及l(fā)ogback簡單的一個原理。 一、logback的使用引入maven依賴 <!--這個依賴直接包含了 logback-core 以及 slf4j-api的依賴--><dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version></dependency>然后就可以直接在代碼中使用slf4j的接口獲取Logger輸出日志了。(配置在下面的章節(jié)介紹) 二、logback的配置配置獲取順序logback在啟動的時候,會按照下面的順序加載配置文件
上面的順序表示優(yōu)先級,使用java -D配置的優(yōu)先級最高,只要獲取到配置后就不會再執(zhí)行下面的流程。相關(guān)代碼可以看 關(guān)于SLF4j的日志輸出級別在slf4j中,從小到大的日志級別依舊是 logback.xml 配置樣例<?xml version='1.0' encoding='UTF-8'?><configuration debug='true' scan='true' scanPeriod='1 seconds'>
<contextName>logback</contextName>
<!--定義參數(shù),后面可以通過${app.name}使用-->
<property name='app.name' value='logback_test'/>
<!--ConsoleAppender 用于在屏幕上輸出日志-->
<appender name='stdout' class='ch.qos.logback.core.ConsoleAppender'>
<!--定義了一個過濾器,在LEVEL之下的日志輸出不會被打印出來-->
<!--這里定義了DEBUG,也就是控制臺不會輸出比ERROR級別小的日志-->
<filter class='ch.qos.logback.classic.filter.ThresholdFilter'>
<level>DEBUG</level>
</filter>
<!-- encoder 默認(rèn)配置為PatternLayoutEncoder -->
<!--定義控制臺輸出格式-->
<encoder>
<pattern>%d [%thread] %-5level %logger{36} [%file : %line] - %msg%n</pattern>
</encoder>
</appender>
<appender name='file' class='ch.qos.logback.core.rolling.RollingFileAppender'>
<!--定義日志輸出的路徑-->
<!--這里的scheduler.manager.server.home 沒有在上面的配置中設(shè)定,所以會使用java啟動時配置的值-->
<!--比如通過 java -Dscheduler.manager.server.home=/path/to XXXX 配置該屬性-->
<file>${scheduler.manager.server.home}/logs/${app.name}.log</file>
<!--定義日志滾動的策略-->
<rollingPolicy class='ch.qos.logback.core.rolling.TimeBasedRollingPolicy'>
<!--定義文件滾動時的文件名的格式-->
<fileNamePattern>${scheduler.manager.server.home}/logs/${app.name}.%d{yyyy-MM-dd.HH}.log.gz </fileNamePattern>
<!--60天的時間周期,日志量最大20GB-->
<maxHistory>60</maxHistory>
<!-- 該屬性在 1.1.6版本后 才開始支持-->
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<triggeringPolicy class='ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy'>
<!--每個日志文件最大100MB-->
<maxFileSize>100MB</maxFileSize>
</triggeringPolicy>
<!--定義輸出格式-->
<encoder>
<pattern>%d [%thread] %-5level %logger{36} [%file : %line] - %msg%n</pattern>
</encoder>
</appender>
<!--root是默認(rèn)的logger 這里設(shè)定輸出級別是debug-->
<root level='trace'>
<!--定義了兩個appender,日志會通過往這兩個appender里面寫-->
<appender-ref ref='stdout'/>
<appender-ref ref='file'/>
</root>
<!--對于類路徑以 com.example.logback 開頭的Logger,輸出級別設(shè)置為warn,并且只輸出到控制臺-->
<!--這個logger沒有指定appender,它會繼承root節(jié)點(diǎn)中定義的那些appender-->
<logger name='com.example.logback' level='warn'/>
<!--通過 LoggerFactory.getLogger('mytest') 可以獲取到這個logger-->
<!--由于這個logger自動繼承了root的appender,root中已經(jīng)有stdout的appender了,自己這邊又引入了stdout的appender-->
<!--如果沒有設(shè)置 additivity='false' ,就會導(dǎo)致一條日志在控制臺輸出兩次的情況-->
<!--additivity表示要不要使用rootLogger配置的appender進(jìn)行輸出-->
<logger name='mytest' level='info' additivity='false'>
<appender-ref ref='stdout'/>
</logger>
<!--由于設(shè)置了 additivity='false' ,所以輸出時不會使用rootLogger的appender-->
<!--但是這個logger本身又沒有配置appender,所以使用這個logger輸出日志的話就不會輸出到任何地方-->
<logger name='mytest2' level='info' additivity='false'/></configuration>配置詳解configuration節(jié)點(diǎn)相關(guān)屬性
configuration子節(jié)點(diǎn)介紹1. contextName節(jié)點(diǎn)設(shè)置日志上下文名稱,后面輸出格式中可以通過定義 %contextName 來打印日志上下文名稱 2.property節(jié)點(diǎn)用來設(shè)置相關(guān)變量,通過key-value的方式配置,然后在后面的配置文件中通過 ${key}來訪問 3.appender 節(jié)點(diǎn)日志輸出組件,主要負(fù)責(zé)日志的輸出以及格式化日志。常用的屬性有name和class
ConsoleAppender:向控制臺輸出日志內(nèi)容的組件,只要定義好encoder節(jié)點(diǎn)就可以使用。 FileAppender:向文件輸出日志內(nèi)容的組件,用法也很簡單,不過由于沒有日志滾動策略,一般很少使用 RollingFileAppender:向文件輸出日志內(nèi)容的組件,同時可以配置日志文件滾動策略,在日志達(dá)到一定條件后生成一個新的日志文件。 appender節(jié)點(diǎn)中有一個子節(jié)點(diǎn) 在RollingFileAppender中,可以配置相關(guān)的滾動策略,具體可以看配置樣例的注釋。 4.logger以及root節(jié)點(diǎn)root節(jié)點(diǎn)和logger節(jié)點(diǎn)其實(shí)都是表示 如果配置了logger,并且通過getLogger('name/class')獲取到這個logger,輸出日志的時候,就會使用這個logger配置的appender輸出,同時還會使用rootLogger配置的appender。我們可以使用logger節(jié)點(diǎn)的 關(guān)于logger的獲取,一般logger是配置name的。我們再代碼中經(jīng)常通過指定的CLass來獲取Logger,比如這樣 也就是說,name可以配置包名,也可以配置自定義名稱。
一些特性的支持在看logback的啟動日志時,看到下面這句話。
大概意思解析logbck配置時不支持totalSizeCap、maxFileSize的配置。后來查了下,果然,totalSizeCap是在1.1.6之后的版本才開始支持的,切換到1.1.7之后就不會出現(xiàn)這句話了。 maxFileSize比較奇怪,試了目前所有的版本都不支持rollingPolicy—maxFileSize的配置方案,如果配置到triggeringPolicy節(jié)點(diǎn)下,又是可以生效的。但是官網(wǎng)給的文檔上又有出現(xiàn)rollingPolicy下面的。
三、實(shí)現(xiàn)原理slf4j是什么slf4j只是一套標(biāo)準(zhǔn),通俗來講,就是定義了一系列接口,它并不提供任何的具體實(shí)現(xiàn)。所以,我們使用這套接口進(jìn)行開發(fā),可以任意的切換底層的實(shí)現(xiàn)框架。 比如,一開始項(xiàng)目用的是log4j的實(shí)現(xiàn),后來發(fā)現(xiàn)log4j的性能太差了,想換成logback,由于我們代碼中都是面向slf4j接口的,這樣我們只要吧log4j的依賴換成logback就可以了。 logback-classic啟動原理我們在調(diào)用 為了解決這個問題,我追蹤了一下代碼,發(fā)現(xiàn)logback-classic底下,有一個slf4j的包. ![]() logback-slf4j實(shí)現(xiàn).png slf4j在初始化時會調(diào)用 比如logback在自己定義的StaticLoggerBinder做了自己組件的初始化工作。下面是網(wǎng)上找的一個時序圖: ![]() slf4j加載時序圖.png 多個依賴包都實(shí)現(xiàn)了slf4j如果引入了多個slf4j的實(shí)現(xiàn)依賴包,那么各個包底下都有 這個問題和java的類加載機(jī)制有關(guān)系,在雙親委派機(jī)制的模型中,這些引入的依賴包通常都是由 舉個例子,我們通過 四、總結(jié)日志組件的使用一般都非常簡單,幾乎所有的項(xiàng)目中都會用到各種各樣的日志組件。但是可能就是由于太簡單了,比較少的人會愿意深入系統(tǒng)的去了解。本人也只是對logback的配置以及一些簡單的原理做了一些了解,并沒有很深入的去看logback的具體實(shí)現(xiàn)。 因此,本文的內(nèi)容大部分都是基于官網(wǎng)的文檔以及網(wǎng)上一些其他關(guān)于logback的博客,雖然也做了一些簡單的測試,但并不保證全部都是正確的。 |
|
|
來自: liang1234_ > 《log》