什么是 Appender
Appender是負責寫記錄事件的組件。Appender 必須實現接口“ch.qos.logback.core.Appender”。該接口的重要方法總結如下:
package ch.qos.logback.core;
import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.FilterAttachable;
import ch.qos.logback.core.spi.LifeCycle;
public interface Appender<E> extends LifeCycle, ContextAware,
FilterAttachable {
public String getName();
public void setName(String name);
void doAppend(E event);
}
Appender 接口里的多數方法都是 getter 和 setting。值得注意的是 doAppend()方法,它唯一的參數是類型E的對象。類型E的實際類型視 logback模塊的不同而不同。在 logback-classic模塊里,E 可能是“ILoggingEvent”類型;在 logback-access 模塊里,E 可能是“AccessEvent”類型。doAppend()方法也許是 logback 框架里最重要的方法,它負責以適當的格式將記錄事件輸出到合適的設備。
Appender 是被命名的實體。因為有名字,所以能被引用。Appender 接口擴展了FilterAttachable 接口,因此 appender 實例可被關聯一個或多個過濾器。
Appender 是最終負責輸出記錄事件的組件。然而,它們可以把實際格式化的任務委托給Layout或Encoder對象。每個layout/encoder都關聯到一個且僅一個appender。有些appender有內置的或固定的事件格式,因此它們不需要也沒有 layout/encoder。例如,SocketAppender在發送記錄事件之前只是簡單地對其進行序列化。
AppenderBase
類 ch.qos.logback.core.AppenderBase 是實現了 Appender 接口的抽象類。AppenderBase提供所有 appender 共享的基本功能,比如設置/獲取名字的方法,其活動狀態和過濾器。
AppenderBase 是 loback 里所有 appender 的超類。盡管是抽象類,AppenderBase 實際上實現了 Appender 接口的 doAppend()方法。代碼更能說明問題:
public synchronized void doAppend(E eventObject) {
// prevent re-entry.
if (guard) {
return;
}
try {
guard = true;
if (!this.started) {
if (statusRepeatCount++ < ALLOWED_REPEATS) {
addStatus(new WarnStatus(
"Attempted to append to non started appender ["
+ name + "].", this));
}
return;
}
if (getFilterChainDecision(eventObject) == FilterReply.DENY)
{
return;
}
// ok, we now invoke derived class' implementation of append
this.append(eventObject);
} catch (Exception e) {
if (exceptionCount++ < ALLOWED_REPEATS) {
addError("Appender [" + name + "] failed to append.", e);
}
} finally {
guard = false;
}
}
這里的 doAppend()方法的實現是同步的,確保不同線程對同一個 appender 的記錄是線程安全的。
這里進行的同步並不總是合適的,logback 帶了與 AppenderBase 非常相似的類ch.qos.logback.core.UnsynchronizedAppenderBase,之后會討論它。
doAppend()方法做的第一件事就是檢查“guard”是否為 true。如果是,則立即退出方法。
如果未設置“guard”,緊接下來的語句就把它設為 true。“guard”確保 doAppend()方法不會遞歸調用自己。
之后的語句里,我們檢查“started”字段是否為 true。如果不是,doAppend()會發出一條警告信息然后返回。換句話說,appender 一旦關閉后,就無法再向它寫入。Appender 對象實現 LifeCycle 接口,意味着它們實現了 start()、stop()和 isStarted()方法。對 appender 的所有屬性都設值后,Joran 調用 start()方法讓 appender 激活自己的屬性。Appender 也許會啟動失敗,比如因為找不到某些屬性,或者因為不同屬性之間互相引用。例如,假設文件創建是截斷模式,那么,FileAppender 在 Append 選項沒確定之前不能作用於 File 選項。這種顯式激活步驟確保 appender 在屬性值被確定之后才能使用屬性。
如果 appender 不能啟動或者已經被停止,則會通過 logback 的內部狀態管理系統發出一條警告消息。嘗試幾次后,為了避免內部狀態系統被同一條警告消息所淹沒,doAppend()方法將停止發出這些警告消息。
接着的 if 語句檢查關聯的過濾器的結果。根據過濾器鏈的判斷結果,事件被拒絕或接受。如果過濾器鏈沒有結果,則事件被默認接受。
doAppend()方法然后調用派生類的append()方法,此方法真正把事件增加到合適的設備。
最后,釋放 guard,允許下一個 doAppend()調用。
在本手冊中,術語“選項(option)”或“屬性(property)”表示用 JavaBeans 內省機制通過 setter 和 getter 方法動態引用的屬性(attribute)。
Logback-core
Logback-core 是其他 logback 模塊的基礎。一般來說,logback-core 里的模塊需要一些細微的定制。不過在下面的幾節理里,我們將講述幾個直接可以使用的 appender。
OutputStreamAppender
OutputStreamAppender 把事件添加到 java.io.OutputStream。該類提供其他 appender 所需的基本服務。用戶通常不直接實例化 OutputStreamAppender 對象。由於 java.io.OutputStream一般無法被方便地映射到字符串,所以無法在配置文件里指定目標 OutputStream 對象。簡而言之,你不能在配置文件里配置 OutputStreamAppender。但這不是說 OutputStreamAppender沒有配置屬性。它的屬性如下。
屬性名 | 類型 | 描述 |
encoder | Encoder | 決定把事件寫入到底層 OutputStreamAppender 的方式。 |
OutputStreamAppender 是另外三個 appender 的超類:ConsoleAppender、FileAppender及其直接子類 RollingFileAppender。下圖演示了 OutputStreamAppender 和其子類的類圖。
ConsoleAppender
ConsoleAppender把事件添加到控制台,更准確地說是System.out或 System.err,默認為前者。ConsoleAppender按照用戶指定的encoder對事件進行格式化。System.out和System.err都是 java.io.PrintStream 類型,因此,它們被包裹在有緩沖 I/O 操作的 OutputStreamWriter 里。
屬性名 | 類型 | 描述 |
encoder | Encoder | 參見 OutputStreamAppender 屬性 |
target | String | 字 符 串 “ System.out ” 或 “ System.err ”。 默 認 為“System.out”。 |
下面是使用 ConsoleAppender 的配置示例。
示例:ConsoleAppender 配置
(logback-examples/src/main/java/chapters/appenders/conf/logback-Console.xml)
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!--encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by
default-->
<encoder>
<pattern>%-4relative [%thread] %-5level - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
FileAppender
FileAppender 是 OutputStreamAppender 的子類,把記錄事件添加到文件。目標文件通過File 選項指定。如果文件已經存在,則根據 Append 屬性追加或清空文件。
屬性名 | 類型 | 描述 |
append | boolean | 如果 true,事件被追加到現存文件尾部。如果 false,清空現存文件。默認為 true。 |
encoder | Encoder | 參見 OutputStreamAppender 屬性file String 被寫入的文件名。如果文件不存在,則創建之。沒有默認值。如果文件的父目錄不存在,FileAppender 會自動創建各級不存在的目錄。 |
prudent | boolean | 在 prudent 模式下,FileAppender 將安全地寫入指定文件,即使其他 FileAppender 實例運行在不同 JVM 上,比如運行在不同主機上。prudent 默認值為 false。prudent 模式意味着 Append 屬性自動設為 true。prudent 模式寫記錄事件時,大約消耗非 prudent 模式的三倍。在一台“普通”的 PC 上,向本地硬盤寫文件,寫一條記錄事件,非 prudent 模式需要 10 微妙,prudent模式需要 30 微妙。也就是非 prudent 模式每秒記錄100000 條事件,prudent 模式每秒 33000 條。不同 JVM 寫入同一個文件時,prudent 模式高效地排列 I/O 操作。所以,由於訪問文件的 JVM 的數量增加,導致每次 I/O 操作都會有延遲。只要 I/O 操作的總數大約是 20 次記錄請求/秒,就可以忽略對性能的影響。每秒 100 次或等多次 I/O 操作會影響性能,此時應當避免prudent 模式。prudent 模式可以與 RollingFileAppender 聯合使用,但有些限制。 |
下面是 FileAppender 的配置文件例子。
示例:FileAppender 配置
(logback-examples/src/main/java/chapters/appenders/conf/logback-fileAppender.xml)
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
<append>true</append>
<!--
encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by
default
-->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
唯一文件名(用時間戳)
在程序開發期,或對於短生命期程序如批量程序,可以在個新程序啟動時創建新記錄文件。用
示例:用時間戳實現名稱唯一的 FileAppender
(logback-examples/src/main/java/chapters/appenders/conf/logback-timestamp.xml)
<configuration>
<!--
Insert the current time formatted as "yyyyMMdd'T'HHmmss" under the
key
"bySecond" into the logger context. This value will be available
to
all subsequent configuration elements.
-->
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<!--
use the previously created timestamp to create a uniquely named
log
file
-->
<file>log-${bySecond}.txt</file>
<encoder>
<pattern>%logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
timestamp 元素有兩個屬性:key 和 datePattern。屬性 key 是變量名,對余下的配置元素可用。屬性 datePattern 表示把當前時間(解析配置文件的時間)轉換成字符串時使用的日期模式,遵從 java.text.SimpleDateFormat 里的約定。
RollingFileAppender
RollingFileAppender 繼承 FileAppender,能夠滾動記錄文件。例如,RollingFileAppender能先記錄到文件“log.txt”,然后當符合某個條件時,變成記錄到其他文件。RollingFileAppender 有兩個與之互動的重要子組件。第一個是 RollingPolicy,負責滾動。
第二個是 TriggeringPolicy,決定是否以及何時進行滾動。所以,RollingPolicy 負責“什么”,TriggeringPolicy 負責“何時”。
要想 RollingFileAppender 起作用,必須同時設置 RollingPolicy 和 TriggeringPolicy。不過,如果 RollingPolicy 也實現了 TriggeringPolicy 接口,那么只需要設置 RollingPolicy。
下面是 RollingFileAppender 的可用屬性。
屬性名 | 類型 | 描述 |
file | String | 參加 FileAppender 屬性 |
append | boolean | 參加 FileAppender 屬性 |
encoder | Encoder | 參見 OutputStreamAppender 屬性 |
rollingPolicy | RollingPolicy | 當發生滾動時,決定 RollingFileAppender 的行為。 |
triggeringPolicy | TriggeringPolicy | 告知 RollingFileAppender 何時激活滾動。 |
prudent | boolean | prudent 模式下不支持 FixedWindowRollingPolicy。RollingFileAppender 支 持 prudent與TimeBasedRollingPolicy 的聯合使用,但有兩個限制:1. 在 prudent 模式,不支持也不允許文件壓縮(不能在一個 JVM 壓縮文件時,讓另一個 JVM 寫文件)。2. 不能設置 FileAppender 的 file 屬性,必須留空。實際上,多數操作系統不允許當一個進程打開文件時又重命名該文件。參加 FileAppender 屬性。 |
滾動策略概述
RollingPolicy 負責滾動步驟,涉及文件移動和重命名。
RollingPolicy 接口如下:
package ch.qos.logback.core.rolling;
import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.rolling.helper.CompressionMode;
import ch.qos.logback.core.spi.LifeCycle;
public interface RollingPolicy extends LifeCycle {
public void rollover() throws RolloverFailure;
public String getActiveFileName();
public CompressionMode getCompressionMode();
public void setParent(FileAppender appender);
}
rollover 方法完成對當前記錄文件的歸檔工作。getActiveFileName()方法計算當前記錄文件(寫實時記錄的地方)的文件名。如 getCompressionMode()方法名所示,RollingPolicy 也負責決定壓縮模式。最后,RollingPolicy 通過 setParent()方法得到一個對其父的引用。
FixedWindowRollingPolicy
當發生滾動時,FixedWindowRollingPolicy 根據如下固定窗口(window)算法重命名文件。
選項“fileNamePattern”代表歸檔(滾動)記錄文件的文件名模式。該選項是必需的,且必需在模式的某處包含標志“%i”。
下面是 FixedWindowRollingPolicy 的可用屬性。
屬性名 | 類型 | 描述 |
minIndex | int | 窗口索引的最小值 |
maxIndex | int | 窗口索引的最大值 |
fileNamePattern | String | 例如,對於最小值和最大值分別是 1 和 3 的文件名模式“MyLogFile%i.log”,會產生歸檔文件 MyLogFile1.log、MyLogFile2.log 和 MyLogFile3.log。該 屬 性 還 可 以 指 定 文 件 壓 縮 選 項 。 例 如“MyLogFile%i.log.zip”表示歸檔文件必須用 zip 格式進行壓縮;還支持“.gz”格式。 |
由於固定窗口滾動策略需要的文件重命名操作與窗口大小一樣多,所以強烈建議不要使用太大的窗口大小。當用戶指定過大的窗口大小時,當前的代碼會自動將窗口大小設為 12。讓我們來看固定窗口滾動策略的一個更具體的例子。假設“minIndex”是 1, “maxIndex”是 3,“fileNamePatter”是“foo%i.log”。
|||||
|-|-|
|滾動文件數量|活動輸出|目標|歸檔記錄文件|描述|
|0 |foo.log| - | 還沒發生滾動,記錄到初始文件。|
|1 | foo.log| foo1.log|第 1 次滾動。foo.log 被重命名為 foo1.log。創建新 foo.log並成為活動輸出目標。|
|2 | foo.log | foo1.log,foo2.log|第 2 次滾動。foo1.log 被重命名為 foo2.log。foo.log 被重命名為 foo1.log。創建新 foo.log 並成為活動輸出目標。|
|3 | foo.log | foo1.log,foo2.log,foo3.log|第 3 次滾動。foo2.log 被重命名為 foo1.log。foo1.log 被重命名為 foo2.log。foo.log 被重命名為 foo1.log。創建新 foo.log 並成為活動輸出目標。|
|4 | foo.log | foo1.log,foo2.log,foo3.log|此時及此后,發生滾動時會先刪除 foo3.log。其他文件按照上面的步驟被重命名。此時及此后,將有3 個歸檔記錄文件和 1 個活動記錄文件。|
下面的配置文件演示了 RollingFileAppender 和 FixedWindowRollingPolicy。注意“file”選項是必需的,即使它與“fileNamePattern”選項有部分重疊信息。
示例:使用 FixedWindowRollingPolicy 的 RollingFileAppender 的示例配置
(logback-examples/src/main/java/chapters/appenders/conf/logback-RollingFixedWindow.xml)
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>testFile.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>testFile.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
TimeBasedRollingPolicy
TimeBasedRollingPolicy 或許是最受流行的滾動策略。它根據時間來制定滾動策略,例如 根 據 日 或 月 。TimeBasedRollingPolicy 既 負 責 滾 動 也 負 責 觸 發 滾 動 。 實 際 上 ,TimeBasedRollingPolicy 同時實現了 RollingPolicy 接口和 TriggeringPolicy 接口。
TimeBasedRollingPolicy 有兩個屬性:必需的“fileNamePattern”和可選的“maxHistory”。
屬性名 | 類型 | 描述 |
fileNamePattern | String | 必需。定義滾動(歸檔)記錄文件的名字。其值應當包含文件名及“%d”格式轉換符。“%d”可以包含一個java.text.SimpleDateFormat 指定的日期時間模式。如果沒有指定日期時間模式,則默認為 yyyy-MM-dd。RollingFileAppender(TimeBasedRollingPolicy 之父)的“file”選項可有可無。通過設置“file”屬性,可以為活動文件和歸檔文件指定不同的位置。當前記錄總是被指向由“file”屬性指定的文件。如果有“file”屬性,則活動文件的名字不會改變。而如果沒有“file”屬性,則活動文件的名字會根據“fileNamePattern”的值每隔一段時間就重新計算一次。下面的例子會解釋這點。“ %d{} ” 里 的 日 期 時 間 模 式 遵 循java.text.SimpleDateFormat 的約定。在 FileNamePattern或日期時間模式里的前置“/”或后置“\”會被當作目錄分隔符。 |
maxHistory | int | 控制被保留的歸檔文件的最大數量,超出數量就刪除舊文件。例如,假設每月滾動,且 maxHistory 是 6,則只保留最近 6 個月的歸檔文件,刪除之前的文件。注意當刪除舊歸檔文件時,那些為了歸檔而創建的目錄也會被刪除。 |
下面是 fileNamePattern 的部分值及其作用。
fileNamePattern | 滾動計划 | 示例 |
/wombat/foo.%d | 每天滾動(在午夜)。因為%d沒有指定日期時間格式,所以使用默認的yyyy-MM-dd,即每天滾動。 | 未設置 file 屬性:在 2006 年11 月 23 日,記錄會輸出到文件/wombat/foo.2006-11-23。在午夜及之后的 24 日,輸出到文件/wombat/foo.2006-11-24。設 置 file 屬 性 為/wombat/foo.txt:活動記錄文件 總 是 /wombat/foo.txt.。 在2006 年 11 月 23 日,記錄會輸出到文件/wombat/foo.txt。在午夜,/wombat/foo.txt 被重命 名 為/wombat/foo.2006-11-23,創建新的/wombat/foo.txt,之后的24 日 , 輸 出 到 文 件/wombat/foo.txt。 |
/wombat/%d{yyyy/MM}/foo.txt | 每月初滾動 | 未設置 file 屬性:在 2006 年10 月,記錄會輸出到文件/wombat/2006/10/foo.txt 。 在10 月 31 日午夜及 11 月,輸出到文件/wombat/2006/11/foo.txt。設 置 file 屬 性 為/wombat/foo.txt:活動記錄文件 總 是 /wombat/foo.txt.。 在2006 年 10 月,記錄會輸出到文件/wombat/foo.txt。在 10月31 日午夜,/wombat/foo.txt被 重 命 名 為/wombat/2006/10/foo.txt,創建新的/wombat/foo.txt,之后的1 個 月 , 輸 出 到 文 件/wombat/foo.txt。在 11 月 30日的午夜,/wombat/foo.txt 被重 命 名 為/wombat/2006/11/foo.txt,依此類推 |
/wombat/foo.%d{yyyy-ww}.log | 每周初滾動。 | 注意每周的第一天是星期幾取 決 於 地 區(locale)同前,只是滾動發生在每周的開頭。 |
/wombat/foo.%d{yyyy-MM-dd_HH}.log | 每小時滾動 | 同前,只是滾動發生在每小時的開頭 |
/wombat/foo.%d{yyyy-MM-dd_HH-mm}.log | 每分鍾滾動 | 同前,只是滾動發生在每分鍾的開頭。 |
所有“\”和“/”都被解釋為目錄分隔符。任何需要的目錄都會被創建。所以你可以輕松地把記錄文件放到不同的目錄。
正如 FixedWindowRollingPolicy,TimeBasedRollingPolicy 支持自動壓縮文件。如果“fileNamePattern”選項以“.gz”或“.zip”結尾,就表示需要壓縮。
屬性名 | 類型 | 描述 |
/wombat/foo.%d.gz | 每天滾動(在午夜),歸檔文件被自動壓縮為GZIP 文件。 | 未設置 file 屬性:在 2006 年 11 月 23 日,記錄會輸出到 文 件 /wombat/Foo.2006-11-23 。 在 午 夜 ,/wombat/foo.txt 被壓縮為/wombat/foo.2009-11-23.gz,之后的 24 日,輸出到文件/wombat/foo.2006-11-24。設置 file 屬性為/wombat/foo.txt:活動記錄文件總是/wombat/foo.txt.。在 2006 年 11 月 23 日,記錄會輸出到 文 件 /wombat/foo.txt 。 在 午 夜 , 在 午 夜 ,/wombat/foo.txt 被壓縮為/wombat/foo.2009-11-23.gz,創建新的/wombat/foo.txt,之后的 24 日,輸出到文件/wombat/foo.txt。 |
屬性“fileNamePattern”有兩個目的。一是,通過學習模式,logback 計算滾動周期。二是,計算每個歸檔文件的名稱。注意,可以為兩種不同的模式指定同一個周期。模式 yyyy-MM和 yyyy@MM 都表示每月滾動,但它們的歸檔文件名不同。
通過設置“file”屬性,你可以為活動記錄文件和歸檔記錄文件指定不同的位置。記錄輸出會被指向“file”屬性指定的文件,所以活動文件的名字不會改變。然而,如果沒有“file”
屬性,則活動文件的名字會根據“fileNamePattern”的值每隔一段時間就重新計算一次。
屬性“maxHistory”控制被保留的歸檔文件的最大數量,超出數量就刪除舊文件。例如,假設每月滾動,且 maxHistory 是 6,則只保留最近 6 個月的歸檔文件,刪除之前的文件。注意當刪除舊歸檔文件時,那些為了歸檔而創建的目錄也會被刪除。
出於某些技術原因,滾動不是時鍾驅動,而是按照記錄事件的到達時間。比如,在 2002年 3 月 8 日,假設“fileNamePattern”是“yyyy-MM-dd”(每日滾動),則午夜過后的第一個記錄事件會觸發滾動。如果,比如說直到 0 點 23 分 47 秒之前都沒有記錄事件,那么滾動發生的實際時間是 3 月 9 日 0 點 23 分 47 秒,而不是 0 點 0 分。因此,根據事件到達的頻率,滾動或許會被延時觸發。不過,在某個時期內產生的所有記錄事件都被輸出到划分該時期的正確的文件,從這個角度看,雖然有延遲,滾動算法仍然是正確的。
下面是 RollingFileAppender 和 TimeBasedRollingPolicy 合作的例子。
示例:使用 TimeBasedRollingPolicy 的 RollingFileAppender 的配置例子
(logback-examples/src/main/java/chapters/appenders/conf/logback-RollingTimeBased.xml)
<configuration>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logFile.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days worth of history -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
下面是在 prudent 模式下,使用 TimeBasedRollingPolicy 的 RollingFileAppender 的配置
例子。
示例:使用 TimeBasedRollingPolicy 的 RollingFileAppender 的配置例子
(logback-examples/src/main/java/chapters/appenders/conf/logback-PrudentTimeBasedRollin
g.xml)
<configuration>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- Support multiple-JVMs writing to the same log file -->
<prudent>true</prudent>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
基於大小和時間的歸檔
有時你也許想按照日期進行歸檔的同時限制每個記錄文件的大小,特別是當后處理工具
對記錄 文件大 小有 限制時 。Logback 為 此提 供了 SizeAndTimeBasedFNATP ,它是
TimeBasedRollingPolicy 的子組件,FNATP 代表“文件命名和觸發策略”。
下面的例子演示了基於大小和時間的記錄文件歸檔。
示例:SizeAndTimeBasedFNATP 配置
(logback-examples/src/main/java/chapters/appenders/conf/logback-sizeAndTime.xml)
<configuration>
<appender name="ROLLING"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.txt</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 100MB -->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="ROLLING" />
</root>
</configuration>
注意“%d”后面的“%i”。在當前時間周期結束之前,每當當前記錄文件達到“maxFileSize”時,就會用遞增索引歸檔,索引從 0 開始。
基於大小和時間的歸檔支持刪除舊歸檔文件。你需要用“maxHistory”屬性指定要保留的周期的數量。當程序停止並重啟時,記錄會從正確的位置繼續,即當前周期的最大索引。
觸發策略概述
TriggeringPolicy 負責指示 RollingFileAppender 在什么時候滾動。
TriggeringPolicy 接口只有一個方法。
package ch.qos.logback.core.rolling;
import java.io.File;
import ch.qos.logback.core.spi.LifeCycle;
public interface TriggeringPolicy<E> extends LifeCycle {
public boolean isTriggeringEvent(final File activeFile, final E
event);
}
isTriggeringEvent()方法有兩個參數,一個是歸檔文件,一個是當前正被處理的記錄事件。
該方法的具體實現根據這兩個參數來決定是否進行滾動。
使用最廣泛的觸發策略是 TimeBasedRollingPolicy,它也是一個滾動策略,上節已講過。
SizeBasedTriggeringPolicy
查看當前活動文件的大小。如果超過指定大小,SizeBasedTriggeringPolicy 會告訴RollingFileAppender 去觸發當前活動文件的滾動。
SizeBasedTriggeringPolicy 只有一個參數:maxFileSize,默認值是 10MB。
根據數字后面不同的后綴,“maxFileSize”可以是 bytes、KB、MB或 GB。比如 5000000,5000KB、5MB和 2GB都是合法值,且前三個等價。
下面是 RollingFileAppender 與 SizeBasedTriggeringPolicy 合作的配置例子,當記錄文件的大小超過 5MB后,會觸發滾動。
示例:使用 SizeBasedTriggeringPolicy 的 RollingFileAppender 的配置
(logback-examples/src/main/java/chapters/appenders/conf/logback-RollingSizeBased.xml)
<configuration>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>test.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>