<code>package</code> <code>com.book.web.controller;</code>
<code>import</code> <code>org.slf4j.Logger;</code>
<code>import</code> <code>org.slf4j.LoggerFactory;</code>
<code>/**</code>
<code> </code><code>* logback的測試</code>
<code> </code><code>* @author liweihan</code>
<code> </code><code>*</code>
<code> </code><code>*/</code>
<code>public</code> <code>class</code> <code>TestLogback {</code>
<code> </code><code>/**</code>
<code> </code><code>1.引入jar包</code>
<code> </code><code><dependency></code>
<code> </code><code><groupId>ch.qos.logback</groupId></code>
<code> </code><code><artifactId>logback-core</artifactId></code>
<code> </code><code><version>1.2.3</version></code>
<code> </code><code></dependency></code>
<code> </code><code><dependency></code>
<code> </code><code><artifactId>logback-classic</artifactId></code>
<code> </code><code><groupId>org.slf4j</groupId></code>
<code> </code><code><artifactId>slf4j-api</artifactId></code>
<code> </code><code><version>1.7.7</version></code>
<code> </code>
<code> </code><code>2.logback 官方使用方式,其實就和slf4j內建了起來</code>
<code> </code><code>下面Logger、LoggerFactory都是slf4j自己的接口與類</code>
<code> </code><code>沒有配置檔案的情況下,使用的是預設配置。搜尋配置檔案的過程如下:</code>
<code> </code><code>尋找logback.configurationFile的系統屬性 →</code>
<code> </code><code>尋找 logback.groovy → </code>
<code> </code><code>尋找 logback-test.xml → </code>
<code> </code><code>尋找 logback.xml </code>
<code> </code>
<code> </code><code>目前路徑都是定死的(放在類路徑下),隻有logback.configurationFile的系統屬性是可以更改的,</code>
<code> </code><code>是以如果我們想更改配置檔案的位置(不想放在類路徑下),則需要設定這個系統屬性:</code>
<code> </code><code>System.setProperty("logback.configurationFile","/path/to/config.xml");</code>
<code> </code><code>解析完配置檔案後,傳回的ILoggerFactory執行個體的類型是LoggerContext(它包含了配置資訊)</code>
<code> </code><code>根據傳回的ILoggerFactory執行個體,來擷取Logger</code>
<code> </code><code>就是根據上述的LoggerContext來建立一個Logger,</code>
<code> </code><code>每個logger與LoggerContext建立了關系,并放到LoggerContext的緩存中</code>
<code> </code>
<code> </code><code>3.如果logback-和commons-logging內建,還需要加入jar包</code>
<code> </code><code><artifactId>jcl-over-slf4j</artifactId></code>
<code> </code><code></dependency> </code>
<code> </code><code>private static Log logger = LogFactory.getLog(TestLogback.class);</code>
<code> </code><code>logback本身的使用其實就和slf4j綁定了起來,現在要想指定commons-logging的底層log實作是logback,則需要2步走</code>
<code> </code><code>第一步: 先将commons-logging底層的log實作轉向slf4j (jcl-over-slf4j幹的事)</code>
<code> </code><code>第二步: 再根據slf4j的選擇底層日志原理,我們使之選擇上logback</code>
<code> </code><code>這樣就可以完成commons-logging與logback的內建。即寫着commons-logging的API,底層卻是logback來進行輸出</code>
<code> </code><code>*/</code>
<code> </code>
<code> </code><code>private</code> <code>static</code> <code>final</code> <code>Logger logger = LoggerFactory.getLogger(TestLogback.</code><code>class</code><code>);</code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(String[] args) {</code>
<code> </code><code>if</code> <code>(logger.isDebugEnabled()) {</code>
<code> </code><code>logger.debug(</code><code>" ====== slf4j-logback debug message"</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>if</code> <code>(logger.isInfoEnabled()) {</code>
<code> </code><code>logger.info(</code><code>" ====== slf4j-logback info message"</code><code>);</code>
<code> </code><code>if</code> <code>(logger.isTraceEnabled()) {</code>
<code> </code><code>logger.trace(</code><code>" ====== slf4j-logback trace message"</code><code>);</code>
<code> </code><code>if</code> <code>(logger.isWarnEnabled()) {</code>
<code> </code><code>logger.error(</code><code>" ====== slf4j-logback error message"</code><code>);</code>
<code> </code><code>}</code>
<code>}</code>
如果我們不配置logback-test.xml或logback.xml,那麼将要調用logback.configurationFile的系統屬性。
logback.xml的配置:
<code><?</code><code>xml</code> <code>version</code><code>=</code><code>"1.0"</code> <code>encoding</code><code>=</code><code>"UTF-8"</code><code>?></code>
<code><!-- if debug set to true, context info always print otherwise the contex</code>
<code> </code><code>info will print when error occour --></code>
<code><</code><code>configuration</code> <code>scan</code><code>=</code><code>"true"</code> <code>scanPeriod</code><code>=</code><code>"20 seconds"</code> <code>debug</code><code>=</code><code>"false"</code><code>></code>
<code> </code><code><</code><code>appender</code> <code>name</code><code>=</code><code>"STDOUT"</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.ConsoleAppender"</code><code>></code>
<code> </code><code><</code><code>encoder</code><code>></code>
<code> </code><code><</code><code>pattern</code><code>>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36}</code>
<code> </code><code>[%file:%line] - %msg%n</code>
<code> </code><code></</code><code>pattern</code><code>></code>
<code> </code><code></</code><code>encoder</code><code>></code>
<code> </code><code></</code><code>appender</code><code>></code>
<code> </code><code><!-- 所有日志檔案 --></code>
<code> </code><code><</code><code>appender</code> <code>name</code><code>=</code><code>"ROLLING"</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.RollingFileAppender"</code><code>></code>
<code> </code><code><</code><code>file</code><code>>${html5.log.path}html5.log</</code><code>file</code><code>></code>
<code> </code><code><</code><code>rollingPolicy</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"</code><code>></code>
<code> </code><code><</code><code>fileNamePattern</code><code>>${html5.log.path}html5.%d{yyyy-MM-dd}.log</code>
<code> </code><code></</code><code>fileNamePattern</code><code>></code>
<code> </code><code><</code><code>maxHistory</code><code>>15</</code><code>maxHistory</code><code>></code>
<code> </code><code></</code><code>rollingPolicy</code><code>></code>
<code> </code><code><</code><code>charset</code><code>>UTF-8</</code><code>charset</code><code>></code>
<code> </code><code><!--2016-07-13-han-add : just for scan error log clearly!--></code>
<code> </code><code><</code><code>appender</code> <code>name</code><code>=</code><code>"ERROR-OUT"</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.RollingFileAppender"</code><code>></code>
<code> </code><code><</code><code>file</code><code>>${html5.log.path}error.log</</code><code>file</code><code>></code>
<code> </code><code><</code><code>filter</code> <code>class</code><code>=</code><code>"ch.qos.logback.classic.filter.LevelFilter"</code><code>></code>
<code> </code><code><</code><code>level</code><code>>ERROR</</code><code>level</code><code>></code>
<code> </code><code><</code><code>onMatch</code><code>>ACCEPT</</code><code>onMatch</code><code>></code>
<code> </code><code><</code><code>onMismatch</code><code>>DENY</</code><code>onMismatch</code><code>></code>
<code> </code><code></</code><code>filter</code><code>></code>
<code> </code><code><</code><code>fileNamePattern</code><code>>${html5.log.path}error.%d{yyyy-MM-dd}.log</code>
<code> </code><code><!--2016-07-13-add-han-just for test some Class or package</code>
<code> </code><code><logger name="com.vis.servlet.PhonePlayServlet" level="DEBUG" additivity="false"></code>
<code> </code><code><appender-ref ref="STDOUT"/></code>
<code> </code><code><appender-ref ref="ROLLING"/></code>
<code> </code><code></logger></code>
<code> </code><code><logger name="com.vis.servlet.PhoneUGCPlayListServlet" level="DEBUG" additivity="false"></code>
<code> </code><code><logger name="com.vis.servlet.PhoneUGCWxServlet" level="DEBUG" additivity="false"></code>
<code> </code><code><logger name="com.vis.servlet.PhoneUGCServlet" level="DEBUG" additivity="false"></code>
<code> </code><code><logger name="com.vis.servlet.PhoneUGCPlayListWxServlet" level="DEBUG" additivity="false"></code>
<code>--></code>
<code> </code><code><</code><code>root</code> <code>level</code><code>=</code><code>"info"</code><code>></code>
<code> </code><code><</code><code>appender-ref</code> <code>ref</code><code>=</code><code>"ROLLING"</code><code>/></code>
<code> </code><code><</code><code>appender-ref</code> <code>ref</code><code>=</code><code>"STDOUT"</code><code>/></code>
<code> </code><code><</code><code>appender-ref</code> <code>ref</code><code>=</code><code>"ERROR-OUT"</code><code>/></code>
<code> </code><code></</code><code>root</code><code>></code>
<code></</code><code>configuration</code><code>></code>
配置說明:
一、根節點<configuration>包含的屬性:
scan:
當此屬性設定為true時,配置檔案如果發生改變,将會被重新加載,預設值為true。
scanPeriod:
設定監測配置檔案是否有修改的時間間隔,如果沒有給出時間機關,預設機關是毫秒。
當scan為true時,此屬性生效。預設的時間間隔為1分鐘。
debug:
當此屬性設定為true時,将列印出logback内部日志資訊,實時檢視logback運作狀态。預設值為false。
例子如上!
二、設定logger
<logger> : 用來設定某一個包或者具體的某一個類的日志列印級别、以及指定<appender>。<logger>僅有一個name屬性,一個可選的level和一個可選的addtivity屬性。
name : 用來指定受此logger限制的某一個包或者具體的某一個類。
level: 用來設定列印級别,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
還有一個特殊值INHERITED或者同義詞NULL,代表強制執行上級的級别。
如果未設定此屬性,那麼目前loger将會繼承上級的級别。
addtivity: 是否向上級loger傳遞列印資訊。預設是true。
<logger>可以包含零個或多個<appender-ref>元素,
辨別這個appender将會添加到這個loger。
<code><!-- 該包所有類的日志的列印,但是并沒用設定列印級别,</code>
<code> </code><code>是以繼承他的上級<root>的日志級别。</code>
<code> </code><code>沒有設定addtivity,預設為true,将此loger的列印資訊向上級傳遞;</code>
<code> </code><code>沒有設定appender,此loger本身不列印任何資訊。</code>
<code><</code><code>logger</code> <code>name</code><code>=</code><code>"com.book.web.controller"</code><code>/></code>
<code><!-- TestLogback類 ,此時該類的日志就不會輸入到檔案中,日志級别為INFO</code>
<code>additivity設定為true時,将列印兩次日志!</code>
<code><</code><code>logger</code> <code>name</code><code>=</code><code>"com.book.web.controller.TestLogback"</code> <code>level</code><code>=</code><code>"INFO"</code> <code>additivity</code><code>=</code><code>"false"</code><code>></code>
<code> </code><code><</code><code>appender-ref</code> <code>ref</code><code>=</code><code>"STDOUT"</code><code>/></code>
<code></</code><code>logger</code><code>></code>
三、設定root
其實,他也是<logger>元素,但是它是根loger。隻有一個level屬性
level:
用來設定列印級别,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能設定為INHERITED或者同義詞NULL。預設是DEBUG
<root>可以包含零個或多個<appender-ref>元素,辨別這個appender将會添加到這個logger。
四、設定appender
<appender>:
<appender>是<configuration>的子節點,是負責寫日志的元件。
<appender>有兩個必要屬性name和class。name指定appender名稱,class指定appender的全限定名。
1.ConsoleAppender:
把日志添加到控制台,有以下子節點:
<encoder>:對日志進行格式化。
<target>:字元串 System.out 或者 System.err ,預設 System.out ;
2.FileAppender:
把日志添加到檔案,有以下子節點:
<file>:被寫入的檔案名,可以是相對目錄,也可以是絕對目錄,如果上級目錄不存在會自動建立,沒有預設值。<append>:如果是 true,日志被追加到檔案結尾,如果是 false,清空現存檔案,預設是true。
<encoder>:對記錄事件進行格式化。(具體參數稍後講解 )
<prudent>:如果是 true,日志會被安全的寫入檔案,即使其他的FileAppender也在向此檔案做寫入操作,效率低,預設是 false。
<code><</code><code>configuration</code><code>> </code>
<code> </code><code><</code><code>appender</code> <code>name</code><code>=</code><code>"FILE"</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.FileAppender"</code><code>> </code>
<code> </code><code><</code><code>file</code><code>>testFile.log</</code><code>file</code><code>> </code>
<code> </code><code><</code><code>append</code><code>>true</</code><code>append</code><code>> </code>
<code> </code><code><</code><code>encoder</code><code>> </code>
<code> </code><code><</code><code>pattern</code><code>>%-4relative [%thread] %-5level %logger{35} - %msg%n</</code><code>pattern</code><code>> </code>
<code> </code><code></</code><code>encoder</code><code>> </code>
<code> </code><code></</code><code>appender</code><code>> </code>
<code> </code>
<code> </code><code><</code><code>root</code> <code>level</code><code>=</code><code>"DEBUG"</code><code>> </code>
<code> </code><code><</code><code>appender-ref</code> <code>ref</code><code>=</code><code>"FILE"</code> <code>/> </code>
<code> </code><code></</code><code>root</code><code>> </code>
3.RollingFileAppender:
滾動記錄檔案,先将日志記錄到指定檔案,當符合某個條件時,将日志記錄到其他檔案。有以下子節點:
<rollingPolicy>:當發生滾動時,決定 RollingFileAppender 的行為,涉及檔案移動和重命名。
<triggeringPolicy >: 告知 RollingFileAppender 合适激活滾動。
<prudent>:當為true時,不支援FixedWindowRollingPolicy。支援TimeBasedRollingPolicy,但是有兩個限制,1不支援也不允許檔案壓縮,2不能設定file屬性,必須留白。
3.1 rollingPolicy:
3.1.1 TimeBasedRollingPolicy: 最常用的滾動政策,它根據時間來制定滾動政策,
既負責滾動也負責出發滾動。有以下子節點:
<fileNamePattern>:
必要節點,包含檔案名及“%d”轉換符, “%d”可以包含一個<code>java.text.SimpleDateFormat指定的時間格式,如:%d{yyyy-MM}。如果直接使用 %d,預設格式是 yyyy-MM-dd。</code>RollingFileAppender 的file位元組點可有可無,通過設定file,可以為活動檔案和歸檔檔案指定不同位置,目前日志總是記錄到file指定的檔案(活動檔案),活動檔案的名字不會改變;如果沒設定file,活動檔案的名字會根據fileNamePattern 的值,每隔一段時間改變一次。“/”或者“\”會被當做目錄分隔符。
<maxHistory>:
可選節點,控制保留的歸檔檔案的最大數量,超出數量就删除舊檔案。假設設定每個月滾動,且<maxHistory>是6,則隻儲存最近6個月的檔案,删除之前的舊檔案。注意,删除舊檔案是,那些為了歸檔而建立的目錄也會被删除。
3.1.2 FixedWindowRollingPolicy: 根據固定視窗算法重命名檔案的滾動政策。有以下子節點:
<minIndex>:視窗索引最小值
<maxIndex>:視窗索引最大值,當使用者指定的視窗過大時,會自動将視窗設定為12。
<fileNamePattern >:
必須包含“%i”例如,假設最小值和最大值分别為1和2,命名模式為 mylog%i.log,會産生歸檔檔案mylog1.log和mylog2.log。還可以指定檔案壓縮選項,例如,mylog%i.log.gz 或者 沒有log%i.log.zip
3.2 triggeringPolicy:
SizeBasedTriggeringPolicy: 檢視目前活動檔案的大小,如果超過指定大小會告知RollingFileAppender 觸發目前活動檔案滾動。隻有一個節點:
<maxFileSize>:這是活動檔案的大小,預設值是10MB。
<code><!-- 每天生成一個檔案,保留15天 --></code>
<code><</code><code>appender</code> <code>name</code><code>=</code><code>"ROLLING"</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.RollingFileAppender"</code><code>></code>
<code> </code><code><</code><code>file</code><code>>log/test.log</</code><code>file</code><code>></code>
<code> </code><code><</code><code>rollingPolicy</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"</code><code>></code>
<code> </code><code><</code><code>fileNamePattern</code><code>>log/test.%d{yyyy-MM-dd}.log</</code><code>fileNamePattern</code><code>></code>
<code> </code><code><</code><code>maxHistory</code><code>>15</</code><code>maxHistory</code><code>></code>
<code> </code><code></</code><code>rollingPolicy</code><code>></code>
<code> </code><code><</code><code>encoder</code><code>></code>
<code> </code><code><</code><code>pattern</code><code>>%d{HH:mm:ss.SSS} [%thread] [%-5level] %logger{50}.%M[%line] - %msg%n</</code><code>pattern</code><code>></code>
<code> </code><code><</code><code>charset</code><code>>UTF-8</</code><code>charset</code><code>></code>
<code> </code><code></</code><code>encoder</code><code>></code>
<code></</code><code>appender</code><code>></code>
<code> </code><code><!-- 按照固定視窗模式生成日志檔案,當檔案大于20MB時,生成新的日志檔案。</code>
<code> </code><code>視窗大小是1到3,當儲存了3個歸檔檔案後,将覆寫最早的日志。 --></code>
<code> </code><code><</code><code>appender</code> <code>name</code><code>=</code><code>"ROLLING2"</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.RollingFileAppender"</code><code>></code>
<code> </code><code><</code><code>file</code><code>>log/html5.log</</code><code>file</code><code>></code>
<code> </code><code><</code><code>rollingPolicy</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.FixedWindowRollingPolicy"</code><code>></code>
<code> </code><code><</code><code>fileNamePattern</code><code>>log/html5.%i.log</</code><code>fileNamePattern</code><code>></code>
<code> </code><code><</code><code>minIndex</code><code>>1</</code><code>minIndex</code><code>></code>
<code> </code><code><</code><code>maxIndex</code><code>>3</</code><code>maxIndex</code><code>></code>
<code> </code><code></</code><code>rollingPolicy</code><code>></code>
<code> </code><code><</code><code>triggeringPolicy</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"</code><code>></code>
<code> </code><code><</code><code>maxFileSize</code><code>>20MB</</code><code>maxFileSize</code><code>></code>
<code> </code><code></</code><code>triggeringPolicy</code><code>></code>
<code> </code><code><</code><code>encoder</code><code>></code>
<code> </code><code><</code><code>pattern</code><code>>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%file:%line] - %msg%n</</code><code>pattern</code><code>></code>
<code> </code><code><</code><code>charset</code><code>>UTF-8</</code><code>charset</code><code>></code>
<code> </code><code></</code><code>encoder</code><code>></code>
<code> </code><code></</code><code>appender</code><code>></code>
五、設定encoder
負責兩件事,一是把日志資訊轉換成位元組數組,二是把位元組數組寫入到輸出流。
目前PatternLayoutEncoder 是唯一有用的且預設的encoder ,有一個<pattern>節點,用來設定日志的輸入格式。使用“%”加“轉換符”方式,如果要輸出“%”,則必須用“\”對“\%”進行轉義。
<pattern>裡面的轉換符說明:
轉換符
作用
c {length }
lo {length }
logger {length }
輸出日志的logger名,可有一個整形參數,功能是縮短logger名,設定為0表示隻輸入logger最右邊點符号之後的字元串。Conversion specifierLogger nameResult%loggermainPackage.sub.sample.BarmainPackage.sub.sample.Bar%logger{0}mainPackage.sub.sample.BarBar%logger{5}mainPackage.sub.sample.Barm.s.s.Bar%logger{10}mainPackage.sub.sample.Barm.s.s.Bar%logger{15}mainPackage.sub.sample.Barm.s.sample.Bar%logger{16}mainPackage.sub.sample.Barm.sub.sample.Bar%logger{26}mainPackage.sub.sample.BarmainPackage.sub.sample.Bar
C {length }
class {length }
輸出執行記錄請求的調用者的全限定名。參數與上面的一樣。盡量避免使用,除非執行速度不造成任何問題。
contextName
cn
輸出上下文名稱。
d {pattern }
date {pattern }
輸出日志的列印日志,模式文法與<code>java.text.SimpleDateFormat</code> 相容。Conversion PatternResult%d2006-10-20 14:06:49,812%date2006-10-20 14:06:49,812%date{ISO8601}2006-10-20 14:06:49,812%date{HH:mm:ss.SSS}14:06:49.812%date{dd MMM yyyy ;HH:mm:ss.SSS}20 oct. 2006;14:06:49.812
F / file
輸出執行記錄請求的java源檔案名。盡量避免使用,除非執行速度不造成任何問題。
caller{depth}caller{depth, evaluator-1, ... evaluator-n}
輸出生成日志的調用者的位置資訊,整數選項表示輸出資訊深度。
例如, %caller{2} 輸出為:
例如, %caller{3} 輸出為:
L / line
輸出執行日志請求的行号。盡量避免使用,除非執行速度不造成任何問題。
m / msg / message
輸出應用程式提供的資訊。
M / method
輸出執行日志請求的方法名。盡量避免使用,除非執行速度不造成任何問題。
n
輸出平台先關的分行符“\n”或者“\r\n”。
p / le / level
輸出日志級别。
r / relative
輸出從程式啟動到建立日志記錄的時間,機關是毫秒
t / thread
輸出産生日志的線程名。
replace(p ){r, t}
p 為日志内容,r 是正規表達式,将p 中符合r 的内容替換為t 。
例如, "%replace(%msg){'\s', ''}"
我自己用的幾個
<code><</code><code>encoder</code><code>></code>
<code> </code><code><!-- --></code>
<code> </code><code><</code><code>pattern</code><code>>%d{HH:mm:ss.SSS} [%thread] [%-5level] %logger{50}.%M[%line] - %msg%n</</code><code>pattern</code><code>></code>
<code> </code><code><!-- 本地調試用 </code>
<code> </code><code><pattern>%d{yyyy/MM/dd-HH:mm:ss} [%level] [%thread] %caller{1}-%msg%n</pattern></code>
<code> </code><code>--></code>
<code> </code><code><!-- </code>
<code> </code><code><Pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [ %-5level ][ %thread ] %logger{56}.%method[%L] - %msg%n</Pattern> --></code>
<code> </code><code><</code><code>pattern</code><code>>%-4relative [%thread] %-5level %logger{35} - %msg%n</</code><code>pattern</code><code>> </code>
<code></</code><code>encoder</code><code>></code>
格式修飾符,與轉換符共同使用:
可選的格式修飾符位于“%”和轉換符之間。
第一個可選修飾符是左對齊 标志,符号是減号“-”;接着是可選的最小寬度 修飾符,用十進制數表示。如果字元小于最小寬度,則左填充或右填充,預設是左填充(即右對齊),填充符為空格。如果字元大于最小寬度,字元永遠不會被截斷。最大寬度 修飾符,符号是點号"."後面加十進制數。如果字元大于最大寬度,則從前面截斷。點符号“.”後面加減号“-”在加數字,表示從尾部截斷。
例如:%-4relative 表示,将輸出從程式啟動到建立日志記錄的時間 進行左對齊 且最小寬度為4。
六、設定Filter
<filter>:過濾器,執行一個過濾器會有傳回1個枚舉值,即DENY,NEUTRAL,ACCEPT其中之一。
傳回DENY,日志将立即被抛棄不再經過其他過濾器;
傳回NEUTRAL,有序清單裡的下個過濾器過接着處理日志;
傳回ACCEPT,日志會被立即處理,不再經過剩餘過濾器。
過濾器被添加到<Appender> 中,為<Appender> 添加一個或多個過濾器後,可以用任意條件對日志進行過濾。<Appender> 有多個過濾器時,按照配置順序執行。
LevelFilter: 級别過濾器,根據日志級别進行過濾。如果日志級别等于配置級别,過濾器會根據onMath 和 onMismatch接收或拒絕日志。有以下子節點:
<level>:設定過濾級别
<onMatch>:用于配置符合過濾條件的操作
<onMismatch>:用于配置不符合過濾條件的操作
例如:将過濾器的日志級别配置為INFO,所有INFO級别的日志交給appender處理,非INFO級别的日志,被過濾掉。
<code><configuration> </code>
<code> </code><code><appender name=</code><code>"CONSOLE"</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.ConsoleAppender"</code><code>> </code>
<code> </code><code><filter </code><code>class</code><code>=</code><code>"ch.qos.logback.classic.filter.LevelFilter"</code><code>> </code>
<code> </code><code><level>INFO</level> </code>
<code> </code><code><onMatch>ACCEPT</onMatch> </code>
<code> </code><code><onMismatch>DENY</onMismatch> </code>
<code> </code><code></filter> </code>
<code> </code><code><encoder> </code>
<code> </code><code><pattern> </code>
<code> </code><code>%-4relative [%thread] %-5level %logger{</code><code>30</code><code>} - %msg%n </code>
<code> </code><code></pattern> </code>
<code> </code><code></encoder> </code>
<code> </code><code></appender> </code>
<code> </code><code><root level=</code><code>"DEBUG"</code><code>> </code>
<code> </code><code><appender-ref ref=</code><code>"CONSOLE"</code> <code>/> </code>
<code> </code><code></root> </code>
<code></configuration></code>
例子2:将錯誤日志單獨到一個檔案error.log中
<code> </code><code><appender name=</code><code>"ERROR-OUT"</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.RollingFileAppender"</code><code>></code>
<code> </code><code><file>log/error.log</file></code>
<code> </code><code><encoder></code>
<code> </code><code><pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{</code><code>36</code><code>}</code>
<code> </code><code></pattern></code>
<code> </code><code><charset>UTF-</code><code>8</code><code></charset></code>
<code> </code><code></encoder></code>
<code> </code><code><filter </code><code>class</code><code>=</code><code>"ch.qos.logback.classic.filter.LevelFilter"</code><code>></code>
<code> </code><code><level>ERROR</level></code>
<code> </code><code><onMatch>ACCEPT</onMatch></code>
<code> </code><code><onMismatch>DENY</onMismatch></code>
<code> </code><code></filter></code>
<code> </code><code><rollingPolicy </code><code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.TimeBasedRollingPolicy"</code><code>></code>
<code> </code><code><fileNamePattern>log/error.%d{yyyy-MM-dd}.log</code>
<code> </code><code></fileNamePattern></code>
<code> </code><code><maxHistory></code><code>15</code><code></maxHistory></code>
<code> </code><code></rollingPolicy></code>
<code> </code><code></appender> </code>
<code> </code><code><root level=</code><code>"DEBUG"</code><code>> </code>
<code> </code><code><appender-ref ref=</code><code>"ERROR-OUT"</code><code>/></code>
<code> </code><code></root> </code>
例子3:當我們需要按時間滾動日志,同時又需要按照大小滾動時:
<code><configuration> </code>
<code> </code><code><appender name=</code><code>"ROLLING"</code> <code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.RollingFileAppender"</code><code>> </code>
<code> </code><code><file>mylog.txt</file> </code>
<code> </code><code><rollingPolicy </code><code>class</code><code>=</code><code>"ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"</code><code>> </code>
<code> </code><code><!-- rollover daily --> </code>
<code> </code><code><fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern> </code>
<code> </code><code><!-- each file should be at most 100MB, keep </code><code>60</code> <code>days worth of history, but at most 20GB --> </code>
<code> </code><code><maxFileSize>100MB</maxFileSize> </code>
<code> </code><code><maxHistory></code><code>60</code><code></maxHistory> </code>
<code> </code><code><totalSizeCap>20GB</totalSizeCap> </code>
<code> </code><code></rollingPolicy> </code>
<code> </code>
<code> </code><code><encoder> </code>
<code> </code><code><pattern>%msg%n</pattern> </code>
<code> </code><code></encoder> </code>
<code> </code><code></appender> </code>
<code> </code><code><root level=</code><code>"DEBUG"</code><code>> </code>
<code> </code><code><appender-ref ref=</code><code>"ROLLING"</code> <code>/> </code>
<code> </code><code></root> </code>
一、
Logback是由log4j創始人Ceki Gülcü設計的又一個開源日志元件。Logback,一個“可靠、通用、快速而又靈活的Java日志架構”。logback目前分成三個子產品:logback-core,logback- classic和logback-access。
logback-core是其它兩個子產品的基礎子產品。
logback-classic是log4j的一個改良版本。
logback-classic完整實作SLF4J API使你可以很友善地更換成其它日志系統如log4j或JDK Logging。logback-access通路子產品與Servlet容器內建提供通過Http來通路日志的功能。
二、
Logback主要建立于Logger、Appender 和 Layout 這三個類之上。
1.
Logger:日志的記錄器,把它關聯到應用的對應的context上後,主要用于存放日志對象,也可以定義日志類型、級别。Logger對象一般多定義為靜态常量.
2.
Appender:用于指定日志輸出的目的地,目的地可以是控制台、檔案、遠端套接字伺服器、 MySQL、 PostreSQL、Oracle和其他資料庫、 JMS和遠端UNIX Syslog守護程序等。
3.
Layout:負責把事件轉換成字元串,格式化的日志資訊的輸出。
三、
Level 有效級别
Logger可以被配置設定級别。級别包括:TRACE、DEBUG、INFO、WARN和ERROR,定義于ch.qos.logback.classic.Level類。程式會列印高于或等于所設定級别的日志,設定的日志等級越高,列印出來的日志就越少。如果設定級别為INFO,則優先級高于等于INFO級别(如:INFO、 WARN、ERROR)的日志資訊将可以被輸出,小于該級别的如DEBUG将不會被輸出。為確定所有logger都能夠最終繼承一個級别,根logger總是有級别,預設情況下,這個級别是DEBUG
四、
三值邏輯
Logback的過濾器基于三值邏輯(ternary logic),允許把它們組裝或成鍊,進而組成任意的複合過濾政策。過濾器很大程度上受到Linux的iptables啟發。這裡的所謂三值邏輯是說,過濾器的傳回值隻能是ACCEPT、DENY和NEUTRAL的其中一個。
如果傳回DENY,那麼記錄事件立即被抛棄,不再經過剩餘過濾器;
如果傳回NEUTRAL,那麼有序清單裡的下一個過濾器會接着處理記錄事件;
如果傳回ACCEPT,那麼記錄事件被立即處理,不再經過剩餘過濾器。
五、
Filter 過濾器
Logback-classic提供兩種類型的過濾器:正常過濾器和TuroboFilter過濾器。Logback整體流程:
Logger 産生日志資訊;
Layout修飾這條msg的顯示格式;
Filter過濾顯示的内容;
Appender具體的顯示,即儲存這日志資訊的地方。
六、參考文章
配置和使用
<a href="http://blog.csdn.net/haidage/article/details/6794509/" target="_blank">http://blog.csdn.net/haidage/article/details/6794509/</a>
<a href="http://blog.csdn.net/haidage/article/details/6794529" target="_blank">http://blog.csdn.net/haidage/article/details/6794529</a>
<a href="http://blog.csdn.net/haidage/article/details/6794540" target="_blank">http://blog.csdn.net/haidage/article/details/6794540</a>
<a href="http://blog.csdn.net/canot/article/details/53340295" target="_blank">http://blog.csdn.net/canot/article/details/53340295</a>
<a href="http://www.cnblogs.com/wenbronk/p/6529161.html" target="_blank">http://www.cnblogs.com/wenbronk/p/6529161.html</a>
<a href="http://blog.csdn.net/iamlihongwei/article/details/56283138" target="_blank">http://blog.csdn.net/iamlihongwei/article/details/56283138</a>
<a href="http://www.cnblogs.com/chenfeng1122/p/6179376.html" target="_blank">http://www.cnblogs.com/chenfeng1122/p/6179376.html</a>
//性能對比
<a href="https://my.oschina.net/OutOfMemory/blog/789267%E3%80%81" target="_blank">https://my.oschina.net/OutOfMemory/blog/789267、</a>
<a href="http://blog.csdn.net/yjh1271845364/article/details/70888262%E3%80%81" target="_blank">http://blog.csdn.net/yjh1271845364/article/details/70888262、</a>
//原理
<a href="https://my.oschina.net/pingpangkuangmo/blog/406618" target="_blank">https://my.oschina.net/pingpangkuangmo/blog/406618</a>
本文轉自韓立偉 51CTO部落格,原文連結:http://blog.51cto.com/hanchaohan/1951737,如需轉載請自行聯系原作者