以下內(nèi)容翻譯整理自logback
官方手冊,地址:logback官方手冊
Appender 是什么承绸?
Logback
將編寫日志事件的任務委托給稱為appenders
的組件。Appenders
必須實現(xiàn)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
接口中的大多數(shù)方法都是setter
和getter
绞绒。只有doAppend()
方法是例外的拦耐,它將一個類型為E
的對象作為參數(shù)耕腾。E
的實際類型將根據(jù)logback
模塊的不同而有所不同。在logback-classic
模塊中杀糯,E
的類型是ILoggingEvent
扫俺,在logback-access
模塊中,E
的類型是AccessEvent
固翰。doAppend()
方法是logback
框架中最重要的方法狼纬。它負責將日志事件以適當?shù)母袷捷敵龅竭m當?shù)妮敵鲈O備。
Appenders
是可以被命名的骂际。這確保了可以通過名稱引用它們疗琉,這是腳本配置中很重要的一個特性。Appender
接口擴展了FilterAttachable
接口歉铝,可以將一個或多個過濾器附加到一個appender
實例盈简。過濾器將在下一章詳細討論。
Appenders
負責最終輸出日志事件犯戏。但是送火,它們可以將日志事件的格式化委托給一個Layout
或一個Encoder
對象拳话。每個Layout
/Encoder
都與一個且僅與一個appender
關聯(lián)先匪。有些appenders
具有內(nèi)置或固定的事件格式,因此弃衍,它們既不需要也沒有Layout
/Encoder
呀非。例如,SocketAppender
只會在通過網(wǎng)絡傳輸日志事件之前對它們進行序列化镜盯。
AppenderBase
ch.qos.logback.core.AppenderBase
類是實現(xiàn)了Appender
接口的一個抽象類岸裙。它提供了所有appenders
共享的基礎功能,例如獲取或設置它們的名稱速缆、激活狀態(tài)降允、布局和過濾器的方法。它是logback
自帶的所有appenders
的超類艺糜。雖然是一個抽象類剧董,AppenderBase
實際上實現(xiàn)了Appender
接口中的doAppend()
方法。下面是實現(xiàn)代碼:
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 the derived class's implementation of append
this.append(eventObject);
} finally {
guard = false;
}
}
這里實現(xiàn)的doAppend()
是一個同步方法破停。因此翅楼,從不同的線程記錄到相同的appender
是線程安全的。當線程(例如T
)執(zhí)行doAppend()
方法時真慢,其他線程隨后的調(diào)用將排隊毅臊,直到T
離開doAppend()
方法,從而確保T
對appender
的獨占訪問黑界。
由于這種同步并不總是合適的管嬉,所以logback
又提供了一個ch.qos.logback.core.UnsynchronizedAppenderBase
皂林,和AppenderBase
類非常類似。為了簡潔起見宠蚂,我們在本文檔的其余部分只討論UnsynchronizedAppenderBase
式撼。
doAppend()
方法做的第一件事是檢查守衛(wèi)是否被設置為true
。如果是求厕,則立即退出著隆。如果不是,則在下一個語句中將其設置為true
呀癣。該保護確保doAppend()
方法不會遞歸地調(diào)用自己美浦。假設一個在append()
方法之外調(diào)用的組件想要記錄一些東西。它的調(diào)用可以直接指向剛才調(diào)用它的相同的追加器项栏,從而導致無限循環(huán)和堆棧溢出浦辨。
在接下來的語句中,我們檢查started
字段是否為true
沼沈。如果不是流酬,doAppend()
將發(fā)送一個警告消息并返回。換句話說列另,一旦一個appender
被關閉了芽腾,就不可能再對它進行寫入。Appender
接口繼承了LifeCycle
接口页衙,這意味著它的實現(xiàn)類也實現(xiàn)了start()
摊滔、stop()
和isStarted()
方法。設置完appender
的所有屬性后店乐,Joran
是logback
的配置框架艰躺,它會調(diào)用start()
方法來通知appender
激活其屬性。根據(jù)其類型的不同眨八,如果某些屬性丟失或由于各種屬性之間的干擾腺兴,appender
可能啟動失敗。例如廉侧,考慮到文件創(chuàng)建依賴于截斷模式页响,在Append
選項的值被確定之前,FileAppender
不能對它的File
選項的值執(zhí)行操作伏穆。顯式激活步驟確保appender
在其屬性的值被知道后對其進行操作拘泞。
如果appender
無法啟動或已經(jīng)停止,將通過logback
的內(nèi)部狀態(tài)管理系統(tǒng)發(fā)出警告消息枕扫。經(jīng)過多次嘗試陪腌,為了避免同一警告消息的副本充斥內(nèi)部狀態(tài)系統(tǒng),doAppend()
方法將停止發(fā)出這些警告。
下一個if
語句檢查附加過濾器的結果诗鸭。根據(jù)過濾器鏈產(chǎn)生的決策染簇,可以拒絕或顯式接受事件。在過濾器鏈沒有做出決定的情況下强岸,默認情況下接受事件锻弓。
然后doAppend()
方法調(diào)用派生類的append()
方法實現(xiàn)。此方法的實際工作是將執(zhí)行將事件附加到適當設備蝌箍。
最后青灼,釋放保護,以便允許隨后的請求調(diào)用doAppend()
方法妓盲。
Logback-core
logback -core
是構建其他logback
模塊的基礎杂拨。提供了幾個定制的的appender
。在接下來的幾節(jié)中悯衬,我們將介紹這幾個的appenders
弹沽。
OutputStreamAppender
OutputStreamAppender
追加事件到一個java.io.OutputStream
。該類提供了其他appender
構建的基礎筋粗。用戶通常不會直接實例化OutputStreamAppender
對象策橘,因為一般來說java.io.OutputStream
類型不能方便地映射到字符串属划,因為無法在配置腳本中指定目標OutputStream
對象轧叽。簡單地說距帅,您不能從配置文件配置OutputStreamAppender
萌腿。然而,這并不意味著OutputStreamAppender
缺乏可配置屬性进统,下面將描述這些屬性。
屬性名稱 | 類型 | 描述 |
---|---|---|
encoder | Encoder | 確定將事件寫入底層OutputStreamAppender 的方式。之后會有專門的一章中介紹編碼器策州。 |
immediateFlush | boolean | 即時刷新的默認值是“true” 。輸出流的立即刷新確保立即寫出日志事件宫仗,并且在應用程序在沒有正確關閉附加程序就退出時不會丟失日志事件够挂。另一方面,將此屬性設置為“false” 可能會使日志吞吐量增加四倍(因人而異)藕夫。但是孽糖,如果在應用程序退出時沒有正確關閉appenders ,那么尚未寫入磁盤的日志事件可能會丟失毅贮。 |
OutputStreamAppender
是其他三個追加器的超類办悟,也就是ConsoleAppender
、FileAppender
滩褥、RollingFileAppender
的超類病蛉。下圖展示了OutputStreamAppender
及其子類的類圖。
ConsoleAppender
ConsoleAppender
,顧名思義铺然,附加在控制臺俗孝,或者更準確地說是System.out
或者System.err
。前者是默認目標魄健。ConsoleAppender
在用戶指定的編碼器的幫助下格式化事件赋铝。編碼器將在下一章中討論。這兩個System.out
和System.err
的類型是java.io.PrintStream
沽瘦,因此革骨,它們是被封裝在OutputStreamWriter
中的緩沖 I/O 操作。
屬性名稱 | 類型 | 描述 |
---|---|---|
encoder | Encoder | 見OutputStreamAppender 的屬性介紹析恋。 |
target | String | 一個字符串值System.out 或者System.err 苛蒲,默認是System.out 。 |
withJansi | boolean | 默認情況下绿满,withJansi 屬性被設置為false 臂外。將withJansi 設置為true 將激活Jansi 庫,該庫在Windows 機器上提供對ANSI 顏色代碼的支持喇颁。在一個Windows 主機上漏健,如果這個屬性被設置為true ,那么您應該在類路徑上添加“org.fusesource.jansi:jansi:1.9” 橘霎。注意蔫浆,Linux 和Mac OS X 等基于unix 的操作系統(tǒng)默認支持ANSI 顏色代碼。 |
下面是一個使用ConsoleAppender
的示例配置姐叁。
<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 %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
FileAppender
FileAppender
是OutputStreamAppender
的一個子類瓦盛,追加日志事件到一個文件中,目標文件由File
選項指定外潜。如果文件已經(jīng)存在原环,根據(jù)append
屬性的值,要么被追加处窥,要么被截斷嘱吗。
屬性名稱 | 類型 | 描述 |
---|---|---|
append | boolean | 如果為true ,事件將追加到現(xiàn)有文件的末尾滔驾。如果append 為false 谒麦,則截斷任何現(xiàn)有文件。append 選項默認為true 哆致。 |
encoder | Encoder | 見OutputStreamAppender 的屬性介紹绕德。 |
file | String | 要寫入的文件的名稱,如果文件不存在摊阀,就創(chuàng)建它耻蛇。在Windows 平臺上剩瓶,文件c:\temp\test.log 應該被寫為c:/temp/test.log 或c:\\temp\\test.log 。File 選項沒有默認值城丧。如果文件的父目錄不存在延曙,F(xiàn)ileAppender會自動創(chuàng)建它。 |
prudent | boolean |
(1)在謹慎模式下亡哄,FileAppender 將安全地寫入指定的文件枝缔,即使存在運行在不同JVM (可能運行在不同主機上)中的其他FileAppender 實例。prudent 的默認值為false 蚊惯。謹慎模式可以與RollingFileAppender 一起使用愿卸。謹慎模式意味著append 屬性被自動設置為true 。(2) prudent 更多地依賴于排他性文件鎖截型。實驗表明趴荸,文件鎖定的開銷大約是編寫日志事件開銷的三倍(x3)。在對本地硬盤上的文件進行寫操作時宦焦,如果關閉了謹慎模式发钝,寫一個日志事件大約需要10微秒。當謹慎模式打開時波闹,寫一個日志事件大約需要30微秒酝豪。(3)謹慎模式有效地序列化所有寫到同一文件的JVM 之間的 I/O 操作。因此精堕,隨著爭用訪問文件的JVM 數(shù)量的增加孵淘,每次 I/O 操作造成的延遲也會增加。只要 I/O 操作的總數(shù)低于每秒20個日志請求歹篓,對性能的影響應該可以忽略不計瘫证。如果每秒生成100個或更多 I/O 操作的應用程序可以看到對性能的影響,應該避免使用謹慎的模式庄撮。(4)當日志文件位于網(wǎng)絡文件系統(tǒng)中時背捌,謹慎模式的成本甚至更高。同樣重要的是重窟,網(wǎng)絡文件系統(tǒng)上的文件鎖有時可能存在嚴重偏差载萌,導致當前擁有鎖的進程在釋放鎖時立即重新獲得鎖惧财。因此巡扇,當一個進程占用日志文件鎖時,其他進程在等待鎖時超時垮衷,直到出現(xiàn)死鎖厅翔。(5)謹慎模式的影響高度依賴于網(wǎng)絡速度和操作系統(tǒng)實現(xiàn)細節(jié)。我們提供了一個非常小的應用程序 FileLockSimulator搀突,它可以幫助您模擬環(huán)境中謹慎模式的行為刀闷。 |
默認情況下,每個日志事件都會立即刷新到底層輸出流。從某種意義上說菌羽,如果應用程序在沒有正確關閉appenders
的情況下退出灶泵,日志事件不會丟失觅彰,這種默認方法更安全。但是卒蘸,為了顯著提高日志吞吐量,您可能需要將immediateFlush
屬性設置為false
翻默。下面是FileAppender
配置文件的一個例子:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
<append>true</append>
<!-- 將immediateFlush設置為false缸沃,以獲得更高的日志吞吐量 -->
<immediateFlush>true</immediateFlush>
<!-- 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>
唯一命名的文件(按時間戳)
在應用程序開發(fā)階段或短期應用程序的情況下,例如修械,批量應用程序趾牧,最好在每次啟動新的應用程序時創(chuàng)建一個新的日志文件。在<timestamp>
元素的幫助下肯污,這非常容易做到翘单。下面是一個例子:
<configuration>
<!-- 插入一個格式為"yyyyMMdd'T'HHmmss"的時間戳"bySecond"到日志記錄器上下文。這個值將是可用于所有后續(xù)配置元素 -->
<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
蹦渣,以及一個可選的timeReference
屬性县恕。key
屬性的值是時間戳名稱,后續(xù)配置元素可以通過引用該名稱將時間戳作為變量剂桥。datePattern
屬性表示用于將當前時間轉換為字符串的日期格式忠烛。日期模式應該遵循SimpleDateFormat
中定義的約定。timeReference
屬性表示時間戳的時間引用权逗。默認值是當前時間美尸。然而,在某些情況下斟薇,可能需要使用上下文出生時間作為時間引用师坎。這可以通過將timeReference
屬性設置為“contextBirth”
來實現(xiàn)。如下所示:
<configuration>
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"
timeReference="contextBirth"/>
...
</configuration>
RollingFileAppender
RollingFileAppender
擴展了FileAppender
堪滨,使其能夠滾動日志文件胯陋。例如,RollingFileAppender
可以將日志記錄到一個名為log.txt
的文件中袱箱,一旦滿足某個條件遏乔,就將其日志記錄目標更改為另一個文件。
RollingFileAppender
有兩個重要的子組件发笔。第一個是RollingPolicy
盟萨,負責滾動所需的操作。第二個子是TriggeringPolicy
了讨,負責什么時候進行觸發(fā)滾動捻激。
要想發(fā)揮任何作用制轰,RollingFileAppender
必須同時設置RollingPolicy
和TriggeringPolicy
。但是胞谭,如果它的RollingPolicy
也實現(xiàn)TriggeringPolicy
接口垃杖,那么只需要顯式地指定前者。下面是RollingFileAppender
的可用屬性:
屬性名稱 | 類型 | 描述 |
---|---|---|
file | String | 見FileAppender 屬性描述丈屹。 |
append | boolean | 見FileAppender 屬性描述缩滨。 |
encoder | Encoder | 見OutputStreamAppender 的屬性介紹。 |
rollingPolicy | RollingPolicy | 在發(fā)生翻轉時指示RollingFileAppender 行為的組件泉瞻。請參閱下面的更多信息脉漏。 |
triggeringPolicy | TriggeringPolicy | 告訴RollingFileAppender 何時激活翻轉過程。請參閱下面的更多信息袖牙。 |
prudent | boolean | 在謹慎模式下不支持FixedWindowRollingPolicy 侧巨。謹慎模式下RollingFileAppender 支持與TimeBasedRollingPolicy 結合使用,有兩個限制:(1)在謹慎模式下鞭达,不支持也不允許文件壓縮司忱。(我們不能讓一個JVM在另一個JVM壓縮文件時寫入文件)(2)FileAppender 的file 屬性必須保持空白。實際上畴蹭,大多數(shù)操作系統(tǒng)都不允許在打開另一個進程時重命名文件坦仍。詳情請參見FileAppender 的屬性描述。 |
滾動策略概述
RollingPolicy
負責包含文件移動和重命名的翻轉過程叨襟。RollingPolicy接口如下所示:
package ch.qos.logback.core.rolling;
import ch.qos.logback.core.FileAppender;
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
方法完成了歸檔當前日志文件所涉及的工作繁扎。調(diào)用getActiveFileName()
方法來計算當前日志文件的文件名(寫入活動日志的地方)。如getCompressionMode
方法所示糊闽,滾動策略還負責確定壓縮模式梳玫。最后,通過setParent
方法向滾動策略提供對其父策略的引用右犹。
TimeBasedRollingPolicy
TimeBasedRollingPolicy
可能是最流行的滾動策略提澎。它定義了一個基于時間的滾動策略,例如按天或按月念链∨渭桑基于時間的滾轉策略同時承擔滾轉和觸發(fā)滾轉的責任。實際上掂墓,TimeBasedTriggeringPolicy
同時實現(xiàn)了RollingPolicy
和TriggeringPolicy
接口谦纱。TimeBasedRollingPolicy
的配置采用一個強制性的fileNamePattern
屬性和幾個可選屬性。
屬性名稱 | 類型 | 描述 |
---|---|---|
fileNamePattern | String |
(1)強制的fileNamePattern 屬性定義了滾動(存檔)日志文件的名稱梆暮。它的值應該由文件名組成服协,加上適當放置的%d 轉換說明符。%d 轉換說明符可以包含java.text.SimpleDateFormat 指定的日期和時間模式啦粹。如果省略了日期和時間模式偿荷,會指定默認模式yyyy-MM-dd 。滾轉周期由fileNamePattern 的值推斷得出唠椭。(2)注意跳纳,可以設置或省略RollingFileAppender (TimeBasedRollingPolicy 的父類)中的file 屬性。通過設置包含FileAppender 的file 屬性贪嫂,您可以解耦活動日志文件的位置和歸檔日志文件的位置寺庄。當前日志總是針對file 屬性指定的文件。因此力崇,當前活動日志文件的名稱不會隨時間而更改斗塘。但是,如果您選擇忽略file 屬性亮靴,那么活動文件將根據(jù)fileNamePattern 的值為每個周期重新計算一次馍盟。下面的例子可以說明這一點。(3)時間和日期模式茧吊,%d{} 中內(nèi)容遵循java.text.SimpleDateFormat 約定贞岭。在fileNamePattern 屬性或日期和時間模式中的任何位置上的正斜杠'/' 或反斜杠'\' 字符都將被解釋為目錄分隔符。(4)多個%d 說明符:可以指定多個%d 說明符搓侄,但其中只能有一個是主說明符瞄桨,即用于推斷滾動周期。所有其他令牌都必須通過傳遞“aux” 參數(shù)標記為輔助性的(參見下面的示例)讶踪。多個%d 說明符允許您在不同于滾轉期間的文件夾結構中組織歸檔文件芯侥。例如,下面所示的文件名模式按年/月組織日志文件夾乳讥,但每天在午夜時會將日志文件滾動按天生成一個文件筹麸。/var/log/%d{yyyy/MM, aux}/myapplication.%d{yyyy-MM-dd}.log (5)時區(qū):在某些情況下,您可能希望根據(jù)不同于主機時區(qū)的時鐘來滾動日志文件雏婶∥锔希可以在%d 轉換說明符中按照日期和時間模式傳遞時區(qū)參數(shù)。例如:aFolder/test.%d{yyyy-MM-dd-HH, UTC}.log 留晚。如果指定的時區(qū)標識符未知或拼寫錯誤酵紫,根據(jù)TimeZone.getTimeZone(String) 方法規(guī)范指定為GMT 時區(qū)。 |
maxHistory | int | 可選的maxHistory 屬性控制要保存的最大歸檔文件數(shù)量错维,異步刪除舊文件奖地。例如,如果您指定每月滾動赋焕,并將maxHistory 設置為6 参歹,就會保存6 個月的存檔文件,刪除6 個月以上的文件隆判。注意犬庇,隨著舊歸檔日志文件的刪除僧界,為日志文件存檔而創(chuàng)建的任何文件夾都將被適當?shù)貏h除。 |
totalSizeCap | int | 可選的totalSizeCap 屬性控制所有存檔文件的總大小臭挽。當超過總大小上限時捂襟,將異步刪除最舊的存檔。totalSizeCap 屬性也需要設置maxHistory 屬性欢峰。此外葬荷,總是先應用“最大歷史”限制,然后應用“總大小上限”限制纽帖。 |
cleanHistoryOnStart | boolean | 如果設置為true 宠漩,將在appender 啟動時執(zhí)行刪除存檔。默認情況下懊直,此屬性設置為false 扒吁。 |
下面是一些fileNamePattern
值,并解釋了它們的效果吹截。
fileNamePattern | Rollover schedule | Example |
---|---|---|
/wombat/foo.%d |
每日翻轉(午夜)瘦陈。由于省略了%d 說明符的時間和日期模式,所以設定了默認模式yyyy-MM-dd 波俄,對應于每天的翻轉晨逝。 |
(1)文件屬性未設置:在2006年11月23日,日志輸出將進入文件/wombat/foo.2006-11-23 懦铺。在午夜和24日剩下的時間里捉貌,日志輸出將定向到/wombat/foo.2006-11-24 。(2)文件屬性設置為/wombat/foo.txt :在2006年11月23日冬念,日志輸出將進入文件/wombat/foo.txt 趁窃。午夜時分,foo.txt 將更名為/wombat/foo.2006-11-23 急前。將創(chuàng)建一個新的/wombat/foo.txt 文件醒陆,11月24日剩余的日志輸出將定向到新的foo.txt 。 |
/wombat/%d{yyyy/MM}/foo.txt |
每月初進行滾轉裆针。 |
(1)文件屬性未設置:在2006年10月刨摩,日志輸出將轉到/wombat/2006/10/foo.txt 。在10月31日午夜之后世吨,在11月的剩余時間里澡刹,日志輸出將定向到/wombat/2006/11/foo.txt 。(2)文件屬性設置為/wombat/foo.txt :活動日志文件將一直是/wombat/foo.txt 耘婚。在2006年10月期間罢浇,日志輸出轉到/wombat/foo.txt 。10月31日午夜,/wombat/foo.txt 將更名為/wombat/2006/10/foo.txt 嚷闭。將創(chuàng)建一個新的/wombat/foo.txt 文件攒岛,11月份剩余時間的日志輸出將放在該文件中。在11月30日午夜凌受,/wombat/foo.txt 將更名為/wombat/2006/11/foo.txt 等阵子。 |
/wombat/foo.%d{yyyy-ww}.log |
在每個星期的第一天滾動思杯。注意胜蛉,一周的第一天取決于地區(qū)。 | 與之前的情況類似色乾,只是每一周的開始都會發(fā)生翻轉誊册。 |
/wombat/foo%d{yyyy-MM-dd_HH}.log |
在每個小時的開始時候翻轉。 | 與以前的情況類似暖璧,只是每小時的開始都會發(fā)生翻轉案怯。 |
/wombat/foo%d{yyyy-MM-dd_HH-mm}.log |
在每一分鐘的開始滾動。 | 與前面的情況類似澎办,只是每分鐘的開始都會發(fā)生翻轉嘲碱。 |
/wombat/foo%d{yyyy-MM-dd_HH-mm, UTC}.log |
在每一分鐘的開始滾動。 | 與前面的情況類似局蚀,只是文件名將用UTC表示麦锯。 |
/foo/%d{yyyy-MM,aux}/%d.log |
每天翻轉。檔案位于包含年和月的文件夾下琅绅。 | 在本例中扶欣,第一個%d 說明符被標記為輔助的。第二個%d 說明符省略了時間和日期模式千扶,是主要的料祠。因此,滾動將每天發(fā)生(%d 的缺省值yyyy-MM-dd )澎羞,文件夾名稱將取決于年份和月份髓绽。例如,在2006年11月期間妆绞,存檔文件將全部放在/foo/2006-11/文件夾例如:/foo/2006-11/2006-11-14.log 顺呕。 |
任何向前或向后斜杠字符都被解釋為文件夾(目錄)分隔符。任何需要的文件夾都將根據(jù)需要創(chuàng)建摆碉。因此塘匣,您可以輕松地將日志文件放在單獨的文件夾中。
TimeBasedRollingPolicy
支持自動文件壓縮巷帝。如果fileNamePattern
選項的值以.gz
或.zip
結尾忌卤,則啟用此功能。
fileNamePattern | Rollover schedule | Example |
---|---|---|
/wombat/foo.%d.gz |
每日滾動(在午夜)與自動GZIP 壓縮存檔文件楞泼。 |
(1)文件屬性未設置:在2009年11月23日期間驰徊,日志輸出將轉到文件/wombat/foo.2009-11-23 笤闯。然而,在午夜棍厂,該文件將被壓縮為/wombat/foo.2009-11-23.gz 颗味。11月24日,日志輸出將定向到/wombat/folder/foo.2009-11-24 牺弹,直到第二天它被滾動浦马。(2)文件屬性設置為/wombat/foo.txt :在2009年11月23日,日志輸出將進入文件/wombat/foo.txt 张漂。在午夜晶默,該文件將被壓縮并重新命名為/wombat/foo.2009-11-23.gz 。將創(chuàng)建一個新的/wombat/foo.txt 文件航攒,11月24日剩余時間的日志輸出將放在該文件中磺陡。11月24日午夜,/wombat/foo.txt 將被壓縮并改名為/wombat/foo.2009-11-24.gz 漠畜,以此類推币他。 |
fileNamePattern
有雙重用途。首先憔狞,通過研究模式蝴悉,logback
計算請求的翻轉周期。其次躯喇,它計算每個存檔文件的名稱辫封。注意,兩種不同的模式可以指定相同的周期性。模式yyyy-MM
和yyyy@MM
都指定了每月的滾動,盡管生成的歸檔文件將使用不同的名稱少欺。
通過設置file
屬性,您可以解耦活動日志文件的位置和存檔日志文件的位置欣福。日志輸出將定向到file
屬性指定的文件中。因此焦履,活動日志文件的名稱不會隨時間而更改拓劝。但是,如果您選擇忽略file
屬性嘉裤,然后根據(jù)fileNamePattern
的值為每個周期重新計算活動文件郑临。通過不設置file
選項,您可以避免文件重命名錯誤屑宠,這些錯誤發(fā)生在存在外部文件句柄在滾轉期間引用日志文件時厢洞。
由于各種技術原因,滾動不是時鐘驅動的,而是取決于日志事件的到來躺翻。例如丧叽,在2002年3月8日,假設fileNamePattern
設置為yyyy-MM-dd
(每日翻轉)公你,午夜后第一個事件的到來將觸發(fā)翻轉踊淳。如果在午夜之后的23分47秒內(nèi)沒有日志記錄事件,那么翻轉實際上將發(fā)生在3月9日凌晨00:23'47陕靠,而不是凌晨0:00迂尝。因此,根據(jù)事件的到達率懦傍,可能會觸發(fā)一些延遲的滾動雹舀。但是芦劣,不管延遲如何粗俱,翻轉算法是正確的,因為在某個時間段內(nèi)生成的所有日志事件都將輸出到分隔該時間段的正確文件中虚吟。
下面是RollingFileAppender
與TimeBasedRollingPolicy
的示例配置寸认。
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logFile.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每日翻轉 -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 將30天的歷史記錄限制在3GB的總大小 -->
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
下一個配置示例演示了在謹慎模式下使用與TimeBasedRollingPolicy
關聯(lián)的RollingFileAppender
。
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 支持多個JVM寫入同一個日志文件 -->
<prudent>true</prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
SizeAndTimeBasedRollingPolicy
有時串慰,您可能希望按日期歸檔文件偏塞,但同時限制每個日志文件的大小,特別是如果之后使用的處理工具對日志文件有大小限制時邦鲫。為了滿足這一需求灸叼,logback
提供了SizeAndTimeBasedRollingPolicy
。
注意庆捺,TimeBasedRollingPolicy
已經(jīng)允許限制歸檔日志文件的總體大小古今。如果只希望限制日志歸檔文件的總體大小,那么上面描述的TimeBasedRollingPolicy
設置totalSizeCap
屬性應該就夠用了滔以。
下面是一個示例配置文件捉腥,演示了基于時間和單個文件大小的日志文件歸檔。
<configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.txt</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 每日翻轉 -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<!-- 每個文件最多100MB你画,保存60天的歷史記錄抵碟,但總大小最多20GB -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="ROLLING" />
</root>
</configuration>
注意%d
之外的%i
轉換符號。%i
和%d
轉換符都是必需的坏匪,每次當前日志文件在當前時間段結束之前達到maxFileSize
時拟逮,將使用一個遞增索引(從0開始)對其進行歸檔。
基于大小和時間的存檔支持刪除舊的存檔文件适滓。您需要使用maxHistory
屬性指定要保存的周期數(shù)敦迄。當應用程序停止并重新啟動時,日志將繼續(xù)記錄在正確的位置,即當前期間的最大索引號颅崩。
在1.1.7
之前的版本中几于,這個文檔提到了一個名為SizeAndTimeBasedFNATP
的組件。但是沿后,考慮到SizeAndTimeBasedFNATP
配置結構比較簡單沿彭,我們不再記錄SizeAndTimeBasedFNATP
。不過尖滚,使用SizeAndTimeBasedFNATP
的早期配置文件將繼續(xù)正常工作喉刘。實際上,SizeAndTimeBasedRollingPolicy
是用SizeAndTimeBasedFNATP
子組件實現(xiàn)的漆弄。
FixedWindowRollingPolicy
當滾動時睦裳,FixedWindowRollingPolicy
根據(jù)下面描述的固定窗口算法重命名文件。fileNamePattern
選項表示歸檔(滾動)日志文件的文件名模式撼唾。此選項是必需的廉邑,并且必須在模式中包含整數(shù)令牌%i
。下面是FixedWindowRollingPolicy
的可用屬性倒谷。
屬性名稱 | 類型 | 描述 |
---|---|---|
minIndex | int | 此選項表示窗口索引的下界蛛蒙。 |
maxIndex | int | 此選項表示窗口索引的上界。 |
fileNamePattern | String | 此選項表示在重命名日志文件時緊跟著FixedWindowRollingPolicy 的模式渤愁。它必須包含字符串%i 牵祟,該字符串表示將插入當前窗口索引值的位置。例如抖格,使用與最小值和最大值為1 和3 關聯(lián)的MyLogFile%i.log 將生成名為MyLogFile1.log 诺苹、MyLogFile2.log 和MyLogFile3.log 的歸檔文件。注意雹拄,文件壓縮也是通過這個屬性指定的收奔。例如,fileNamePattern 設置為MyLogFile%i.log.zip 办桨,這意味著存檔文件必須使用zip 格式進行壓縮筹淫;還支持gz 格式。 |
由于固定窗口滾動策略需要的文件重命名操作與窗口大小一樣多呢撞,因此強烈建議不要使用較大的窗口大小损姜。當用戶指定較大的值時,當前實現(xiàn)將自動將窗口大小減小到20殊霞。
讓我們來看一個關于固定窗口翻轉策略的更具體的例子摧阅。假設minIndex
設置為1
,maxIndex
設置為3
绷蹲,fileNamePattern
屬性設置為foo%i.log
棒卷。file
屬性被設置為foo.log
顾孽。
滾動數(shù)量 | 活動輸出目標 | 存檔日志文件 | 描述 |
---|---|---|---|
0 | foo.log | - | 還沒有發(fā)生滾轉,將日志返回到初始文件比规。 |
1 | foo.log | foo1.log | 第一次翻轉若厚。foo.log 被重命名為foo1.log 。創(chuàng)建一個新的foo.log 文件并成為活動輸出目標蜒什。 |
2 | foo.log | foo1.log, foo2.log | 第二次翻轉测秸。將foo1.log 重命名為foo2.log 。foo.log 被重命名為foo1.log 灾常。創(chuàng)建一個新的foo.log 文件并成為活動輸出目標霎冯。 |
3 | foo.log | foo1.log, foo2.log, foo3.log | 第三個翻轉。將foo2.log 重命名為foo3.log 钞瀑。將foo1.log 重命名為foo2.log 沈撞。foo.log 被重命名為foo1.log 。創(chuàng)建一個新的foo.log 文件并成為活動輸出目標雕什。 |
4 | foo.log | foo1.log, foo2.log, foo3.log | 在這輪和隨后的幾輪中缠俺,滾動從刪除log.foo3.log 開始。其他文件通過增加索引重命名监徘,如前面的步驟所示晋修。在接下來的滾動中,將一直有三個歸檔日志和一個活動日志文件凰盔。 |
下面的配置文件給出了一個配置RollingFileAppender
和FixedWindowRollingPolicy
的示例。注意倦春,File
選項是強制性的户敬,即使它包含與fileNamePattern
選項所傳遞的一些相同的信息。
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>test.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>tests.%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>
觸發(fā)策略概述
TriggeringPolicy
實現(xiàn)負責指示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()
將活動文件和當前正在處理的日志事件作為參數(shù)。具體實現(xiàn)根據(jù)這些參數(shù)確定是否應該發(fā)生翻轉呢堰。
最廣泛使用的觸發(fā)策略是TimeBasedRollingPolicy抄瑟,它也是滾動策略的兩倍,前面已經(jīng)與其他滾動策略一起討論過枉疼。
SizeBasedTriggeringPolicy
SizeBasedTriggeringPolicy
查看當前活動文件的大小皮假。如果它的大小超過指定的大小,它將向擁有的RollingFileAppender
發(fā)出信號骂维,觸發(fā)現(xiàn)有活動文件的翻轉惹资。
SizeBasedTriggeringPolicy
只接受一個參數(shù)maxFileSize
,默認值為10MB
航闺。
maxFileSize
選項可以用字節(jié)褪测、千字節(jié)猴誊、兆字節(jié)或千兆字節(jié)來指定,方法是分別用KB
侮措、MB
和GB
作為數(shù)字值的后綴懈叹。例如,5000000
分扎、5000KB
项阴、5MB
和2GB
都是有效值,前三個值是等價的笆包。
下面是一個帶有RollingFileAppender
的示例配置环揽,它與SizeBasedTriggeringPolicy
一起在日志文件達到5MB時觸發(fā)翻轉。
<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>
Logback Classic
雖然日志事件在logback-core
中是通用的庵佣,但在logback-classic
中歉胶,它們始終是ILoggingEvent
的實例。Logback-classic
不過是一個專門處理ILoggingEvent
實例的管道巴粪。
SocketAppender 和 SSLSocketAppender
到目前為止通今,所涉及的appenders
只能記錄日志到本地資源。相反肛根,SocketAppender
的設計目的是通過網(wǎng)絡傳輸序列化的ILoggingEvent
實例來記錄日志到遠程實體辫塌。當使用SocketAppender
時,線路上的日志事件將以明文形式發(fā)送派哲。然而臼氨,當使用SSLSocketAppender
時,日志事件是通過安全通道傳遞的芭届。
序列化事件的實際類型是LoggingEventVO
储矩,它實現(xiàn)了ILoggingEvent
接口。然而褂乍,就日志事件而言持隧,遠程日志記錄是非侵入性的。在反序列化后的接收端逃片,可以像在本地生成一樣記錄事件屡拨。運行在不同機器上的多個SocketAppender
實例可以將它們的日志輸出定向到格式固定的中央日志服務器。SocketAppender
不接受關聯(lián)的layout
褥实,因為它將序列化的事件發(fā)送到遠程服務器呀狼。SocketAppender
運行在傳輸控制協(xié)議(TCP
)層之上,TCP
層提供了一個可靠的性锭、有序的赠潦、流控制的端到端八位字節(jié)流。因此草冈,如果遠程服務器是可訪問的她奥,那么日志事件最終將到達那里瓮增。如果遠程服務器關閉或無法訪問,日志事件將被刪除哩俭。當服務器恢復時绷跑,事件傳輸將透明地恢復。這種透明的重連接由一個連接器線程執(zhí)行凡资,該線程定期嘗試連接到服務器砸捏。
日志事件由本機TCP
實現(xiàn)自動緩沖。這意味著隙赁,如果到服務器的鏈接很慢垦藏,但是仍然比客戶機生成事件的速度快,客戶機將不會受到慢速網(wǎng)絡連接的影響伞访。但是掂骏,如果網(wǎng)絡連接比事件生成的速度慢,那么客戶機只能以網(wǎng)絡速度前進厚掷。特別是在連接到服務器的網(wǎng)絡連接關閉的極端情況下弟灼,客戶機最終將被阻塞∶昂冢或者田绑,如果網(wǎng)絡鏈接已打開,但服務器已關閉抡爹,則不會阻塞客戶機掩驱,盡管日志事件將由于服務器不可用而丟失。
即使SocketAppender
不再附加到任何日志程序豁延,它也不會在連接器線程存在時被垃圾回收昙篙。連接器線程僅在與服務器的連接關閉時才存在。為了避免這種垃圾收集問題诱咏,您應該顯式地關閉SocketAppender
。長生命周期應用程序會創(chuàng)建/銷毀許多SocketAppender
實例缴挖,應該注意這個垃圾收集問題袋狞。大多數(shù)其他應用程序可以安全地忽略它。如果托管SocketAppender
的JVM
在SocketAppender
關閉之前(顯式關閉或垃圾收集之后關閉)退出映屋,那么管道中可能會丟失未傳輸?shù)臄?shù)據(jù)链蕊。這是基于Windows
系統(tǒng)的常見問題放典。為了避免丟失數(shù)據(jù),通常可以顯式地關閉SocketAppender()
沪饺,或者在退出應用程序之前調(diào)用LoggerContext
的stop()
方法。
遠程服務器由remoteHost
和port
屬性標識江醇。下表列出了SocketAppender
屬性。SSLSocketAppender
支持許多額外的配置屬性默责,這些屬性將在“使用SSL”一節(jié)中詳細介紹。
屬性名稱 | 類型 | 描述 |
---|---|---|
includeCallerData | boolean |
includeCallerData 選項接受一個布爾值咸包。如果為true 桃序,則調(diào)用方數(shù)據(jù)將對遠程主機可用。默認情況下烂瘫,不會向服務器發(fā)送調(diào)用方數(shù)據(jù)媒熊。 |
port | int | 遠程服務器的端口號。 |
reconnectionDelay | Duration |
reconnectionDelay 選項接受一個持續(xù)時間字符串坟比,比如“10秒”芦鳍,表示每次嘗試連接到服務器失敗之間的等待時間。這個選項的默認值是30 秒葛账。將此選項設置為0 將關閉重連接功能柠衅。注意,在成功連接到服務器的情況下注竿,將不存在連接器線程茄茁。 |
queueSize | int |
queueSize 屬性接受一個整數(shù)(大于零),該整數(shù)表示要保留的日志事件數(shù)量巩割,以便交付給遠程接收器裙顽。當隊列大小為1 時,發(fā)送到遠程接收器的事件是同步的宣谈。當隊列大小大于1 時愈犹,假設隊列中有可用空間,就會將新事件加入隊列闻丑。使用大于1 的隊列長度可以通過消除由臨時網(wǎng)絡延遲引起的阻塞從而提高性能漩怎。還可參考eventDelayLimit 屬性。 |
eventDelayLimit | Duration |
eventDelayLimit 選項接受一個持續(xù)時間字符串嗦嗡,比如“10秒”勋锤。它表示在本地隊列已滿(即已經(jīng)包含queueSize 事件)時,在刪除事件之前等待的時間侥祭。如果遠程主機持續(xù)緩慢地接受事件叁执,可能會發(fā)生這種情況。此選項的默認值為100 毫秒矮冬。 |
remoteHost | String | 服務器的主機名谈宛。 |
ssl | SSLConfiguration | 僅支持SSLSocketAppender ,此屬性表示appender 將使用SSL 配置胎署,如“使用SSL”中所述吆录。 |
日志服務器選項
標準的Logback-Classic
為服務器提供了兩個選項,用于接收來自SocketAppender
或SSLSocketAppender
的日志事件琼牧。
-
ServerSocketReceiver
及其支持SSL-enabled
程序的SSLServerSocketReceiver
是接收器組件恢筝,可以在應用程序的logback.xml
配置文件中配置這些組件哀卫,以便從遠程套接字追加器接收事件。有關配置細節(jié)和使用示例滋恬,請參見接收器Receivers
的介紹聊训。 -
SimpleSocketServer
及其支持SSL-enabled
程序的SimpleSSLSocketServer
都提供了易于使用的獨立Java
應用程序,該應用程序的設計目的是配置并從shell
的命令行接口運行恢氯。這些應用程序只是等待來自SocketAppender
或SSLSocketAppender
客戶機的日志事件带斑。每個接收到的事件都根據(jù)本地服務器策略進行日志記錄。下面給出了使用示例勋拟。
使用 SimpleSocketServer
SimpleSocketServer
應用程序接受兩個命令行參數(shù):port
和configFile
勋磕;其中port
是要監(jiān)聽的端口,configFile
是XML格式的配置腳本敢靡。
假設您在logback-examples/
目錄中挂滓,使用以下命令啟動SimpleSocketServer
:
java ch.qos.logback.classic.net.SimpleSocketServer 6000 \
src/main/java/chapters/appenders/socket/server1.xml
這里6000
是要監(jiān)聽的端口號,server1.xml
是一個配置腳本啸胧,它向根日志記錄器添加了一個ConsoleAppender
和一個RollingFileAppender
赶站。啟動SimpleSocketServer
之后,您可以使用SocketAppender
從多個客戶機向它發(fā)送日志事件纺念。與本手冊相關的例子包括兩個這樣的客戶端:chapters.appenders.SocketClient1
和chapters.appenders.SocketClient2
兩個客戶機都在等待用戶在控制臺上輸入一行文本贝椿。文本被封裝在一個debug
級別的日志事件中,然后發(fā)送到遠程服務器陷谱。這兩個客戶機在SocketAppender
的配置上有所不同烙博。SocketClient1
以編程方式配置追加器,而SocketClient2
需要配置文件烟逊。
假設SimpleSocketServer
在本地主機上運行渣窜,您可以使用以下命令連接到它:
java chapters.appenders.socket.SocketClient1 localhost 6000
您鍵入的每一行都應該出現(xiàn)在上一步中啟動的SimpleSocketServer
的控制臺。如果停止并重啟SimpleSocketServer
宪躯,客戶機將透明地重新連接到新服務器實例乔宿,盡管斷開連接時生成的事件將簡單地(并且不可挽回地)丟失。
與SocketClient1
不同访雪,示例應用程序SocketClient2
本身并不配置logback
予颤。它需要XML
格式的配置文件。如下所示的配置文件client1.xml
創(chuàng)建了一個SocketAppender
并將其附加到根日志記錄器冬阳。
<configuration>
<appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
<remoteHost>${host}</remoteHost>
<port>${port}</port>
<reconnectionDelay>10000</reconnectionDelay>
<includeCallerData>${includeCallerData}</includeCallerData>
</appender>
<root level="DEBUG">
<appender-ref ref="SOCKET" />
</root>
</configuration>
注意,在上面的配置腳本中党饮,remoteHost
肝陪、port
和includeCallerData
屬性的值不是直接給出的,而是作為替代變量鍵給出的刑顺。變量的值可以指定為系統(tǒng)屬性:
java -Dhost=localhost -Dport=6000 -DincludeCallerData=false \
chapters.appenders.socket.SocketClient2 src/main/java/chapters/appenders/socket/client1.xml
該命令的結果應該與前面的SocketClient1
示例類似氯窍。
請允許我們重復一遍饲常,以強調(diào)日志事件的序列化不具有侵入性。反序列化事件與任何其他日志事件攜帶相同的信息狼讨。它可以像在本地生成一樣進行操作贝淤;除了默認情況下序列化日志事件不包含調(diào)用方數(shù)據(jù)之外。這里有一個例子來說明這一點政供。首先播聪,使用以下命令啟動SimpleSocketServer
:
java ch.qos.logback.classic.net.SimpleSocketServer 6000 \
src/main/java/chapters/appenders/socket/server2.xml
配置文件server2.xml
創(chuàng)建一個ConsoleAppender
,其布局輸出調(diào)用者的文件名和行號以及其他信息布隔。如果像以前一樣使用配置文件client1.xml
運行SocketClient2
离陶,你會注意到服務器端的輸出將包含兩個問號之間的括號,而不是文件名和行號的調(diào)用者:
2006-11-06 17:37:30,968 DEBUG [Thread-0] [?:?] chapters.appenders.socket.SocketClient2 - Hi
通過將includeCallerData
選項設置為true
衅檀,指示SocketAppender
包含調(diào)用方數(shù)據(jù)招刨,可以很容易地更改結果。使用下面的命令就可以了:
java -Dhost=localhost -Dport=6000 -DincludeCallerData=true \
chapters.appenders.socket.SocketClient2 src/main/java/chapters/appenders/socket/client1.xml
由于反序列化事件可以與本地生成的事件以相同的方式處理哀军,甚至可以將它們發(fā)送到另一臺服務器進行進一步處理沉眶。作為練習,您可能希望設置兩個服務器杉适,其中第一個服務器將其接收到的事件從客戶機傳輸?shù)降诙€服務器谎倔。
使用 SimpleSSLSocketServer
SimpleSSLSocketServer
和SimpleSocketServer
一樣,也需要port
和configFile
命令行參數(shù)淘衙。此外传藏,必須使用命令行中指定的系統(tǒng)屬性為日志服務器的X.509
憑證提供位置和密碼。
假設您在logback-examples/
目錄中彤守,使用以下命令啟動SimpleSSLSocketServer
:
java -Djavax.net.ssl.keyStore=src/main/java/chapters/appenders/socket/ssl/keystore.jks \
-Djavax.net.ssl.keyStorePassword=changeit \
ch.qos.logback.classic.net.SimpleSSLSocketServer 6000 \
src/main/java/chapters/appenders/socket/ssl/server.xml
本例使用只適合于測試和實驗的X.509
憑據(jù)運行SimpleSSLSocketServer
毯侦。在生產(chǎn)設置中使用SimpleSSLSocketServer
之前,您應該獲得一個適當?shù)?code>X.509憑據(jù)來標識您的日志服務器具垫。有關詳細信息侈离,請參見"使用SSL"。
因為服務器配置在根元素上指定debug="true"
筝蚕,您將在服務器的啟動日志中看到將要使用的SSL
配置卦碾。這對于驗證本地安全策略實現(xiàn)是否正確非常有用。
運行SimpleSSLSocketServer
后起宽,可以使用SSLSocketAppender
連接到服務器洲胖。下面的示例顯示了所需的appender
配置:
<configuration debug="true">
<appender name="SOCKET" class="ch.qos.logback.classic.net.SSLSocketAppender">
<remoteHost>${host}</remoteHost>
<port>${port}</port>
<reconnectionDelay>10000</reconnectionDelay>
<ssl>
<trustStore>
<location>${truststore}</location>
<password>${password}</password>
</trustStore>
</ssl>
</appender>
<root level="DEBUG">
<appender-ref ref="SOCKET" />
</root>
</configuration>
注意,與前面的示例一樣坯沪,remoteHost
绿映、port
的值是使用替換的變量鍵指定的。此外,請注意ssl
屬性及其嵌套的trustStore
屬性的存在叉弦,該屬性指定存儲的位置和密碼丐一。這個配置是必要的,因為我們的示例服務器使用的是自簽名證書淹冰。有關SSLSocketAppender
的SSL
配置屬性的更多信息库车,請參見“使用SSL”。
通過在命令行上指定替換變量值作為系統(tǒng)屬性樱拴,我們可以使用這種配置運行客戶機應用程序:
java -Dhost=localhost -Dport=6000 \
-Dtruststore=file:src/main/java/chapters/appenders/socket/ssl/truststore.jks \
-Dpassword=changeit \
chapters.appenders.socket.SocketClient2 src/main/java/chapters/appenders/socket/ssl/client.xml
與前面的示例一樣柠衍,您可以在客戶機應用程序提示時輸入一條消息,消息將被發(fā)送到日志服務器(現(xiàn)在通過一個安全通道)疹鳄,并顯示在控制臺拧略。
注意,命令行上給出的truststore
屬性指定一個文件URL
瘪弓,該URL
標識可信任的存儲位置垫蛆。您還可以使用類路徑URL
,如“使用SSL”中所述腺怯。
正如我們前面在服務器啟動時看到的袱饭,由于客戶機配置在根元素上指定了debug="true"
,客戶機的啟動日志記錄包括SSL
配置的詳細信息呛占,以幫助審查本地策略的一致性虑乖。
ServerSocketAppender 和 SSLServerSocketAppender
前面討論的SocketAppender
組件(及其支持ssl
的對應組件)旨在允許應用程序通過網(wǎng)絡連接到遠程日志服務器,以便向服務器交付日志事件晾虑。
在某些情況下疹味,讓應用程序啟動到遠程日志服務器的連接可能不方便或不可行。對于這些情況帜篇,Logback
提供ServerSocketAppender
糙捺。
不啟動到遠程日志服務器的連接,ServerSocketAppender
被動地監(jiān)聽TCP
套接字笙隙,等待來自遠程客戶機的傳入連接洪灯。提交到附加器的日志事件分布到每個連接的客戶機。當沒有客戶機連接時發(fā)生的日志事件將被立即丟棄竟痰。
除了基本的ServerSocketAppender
之外签钩,Logback
還提供了SSLServerSocketAppender
,它使用一個安全加密的通道將日志事件分發(fā)給每個連接的客戶機坏快。此外铅檩,啟用ssl
的appender
完全支持基于證書的相互認證,可以使用這種認證確保只有經(jīng)過授權的客戶端才能連接到appender
來接收日志事件莽鸿。
為在線路上傳輸而編碼日志事件的方法與SocketAppender
使用的方法相同柠并;每個事件都是ILoggingEvent
的序列化實例。只有連接啟動的方向是相反的。SocketAppender
在建立到日志服務器的連接時充當主動對等點臼予,而ServerSocketAppender
是被動的;它偵聽來自客戶機的傳入連接啃沪。
ServerSocketAppender
子類型僅用于Logback
接收器組件粘拾。有關此組件類型的附加信息,請參見接收器创千。ServerSocketAppender
支持以下配置屬性:
屬性名稱 | 類型 | 描述 |
---|---|---|
address | String | 附加程序將偵聽的本地網(wǎng)絡接口地址缰雇。如果未指定此屬性,則追加器將偵聽所有網(wǎng)絡接口追驴。 |
includeCallerData | boolean | 如果為真械哟,則調(diào)用方數(shù)據(jù)將對遠程主機可用。默認情況下殿雪,不會向客戶機發(fā)送調(diào)用方數(shù)據(jù)暇咆。 |
port | int | 附加程序將偵聽的端口號。 |
ssl | SSLConfiguration | 僅支持SSLServerSocketAppender 丙曙,此屬性提供了將由appender 使用的SSL 配置爸业,如“使用SSl”中所述。 |
下面的示例演示了一個使用ServerSocketAppender
的配置:
<configuration debug="true">
<appender name="SERVER"
class="ch.qos.logback.classic.net.server.ServerSocketAppender">
<port>${port}</port>
<includeCallerData>${includeCallerData}</includeCallerData>
</appender>
<root level="debug">
<appender-ref ref="SERVER" />
</root>
</configuration>
注意亏镰,此配置與前面的示例不同扯旷,僅在為appender
指定的類中使用ServerSocketAppender
,并且在沒有remoteHost
屬性的情況下——此appender
被動地等待來自遠程主機的入站連接索抓,而不是打開到遠程日志服務器的連接钧忽。
下面的示例演示了使用SSLServerSocketAppender
的配置。
<configuration debug="true">
<appender name="SERVER"
class="ch.qos.logback.classic.net.server.SSLServerSocketAppender">
<port>${port}</port>
<includeCallerData>${includeCallerData}</includeCallerData>
<ssl>
<keyStore>
<location>${keystore}</location>
<password>${password}</password>
</keyStore>
</ssl>
</appender>
<root level="debug">
<appender-ref ref="SERVER" />
</root>
</configuration>
此配置與前一個配置之間的主要區(qū)別在于逼肯,appender
的class
屬性標識了SSLServerSocketAppender
類型耸黑,以及嵌套ssl
元素的存在,在本例中汉矿,嵌套ssl
元素指定了包含附加器X.509
憑據(jù)的密鑰存儲庫的配置崎坊。有關SSL
配置屬性的信息,請參閱“使用SSL”洲拇。
因為ServerSocketAppender
子類型被設計用于與接收器組件一起使用奈揍,所以我們將接收器的章節(jié)提供使用示例。
SMTPAppender
SMTPAppender
將日志事件累積到一個或多個固定大小的緩沖區(qū)中赋续,并在發(fā)生用戶指定的事件后通過電子郵件發(fā)送適當緩沖區(qū)的內(nèi)容男翰。SMTP
電子郵件傳輸(發(fā)送)是異步執(zhí)行的。默認情況下纽乱,電子郵件傳輸由級別錯誤的日志事件觸發(fā)蛾绎。此外,默認情況下,所有事件都使用一個緩沖區(qū)租冠。
下表總結了SMTPAppender
的各種性能鹏倘。
屬性名稱 | 類型 | 描述 |
---|---|---|
smtpHost | String |
SMTP 服務器的主機名。這個參數(shù)是強制性的顽爹。 |
smtpPort | int |
SMTP 服務器正在監(jiān)聽的端口纤泵。默認為25。 |
to | String | 收件人的電子郵件地址镜粤。會將觸發(fā)事件作為每個發(fā)出電子郵件的內(nèi)容捏题。可以通過用逗號分隔目標地址來指定多個收件人肉渴。另外公荧,還可以使用多個<to> 元素指定多個收件人。 |
from | String |
SMTPAppender 以通常的電子郵件地址格式發(fā)送的電子郵件的發(fā)起者同规。如果您希望包含發(fā)送者的名稱循狰,則使用“Adam Smith <smith@moral.org>” 格式,以便消息顯示為源自“Adam Smith <smith@moral.org>” 。 |
subject | String | 郵件的主題。它可以是PatternLayout 作為有效轉換模式接受的任何值瘤睹。布局將在下一章討論。發(fā)出的電子郵件消息將具有與在觸發(fā)電子郵件消息的日志事件上應用模式相對應的主題行昧识。假設subject 選項設置為“Log: %logger - %msg” ,并且觸發(fā)事件的日志程序名為“com.foo.Bar” 盗扒,并包含消息“Hello world” 跪楞,然后發(fā)出的電子郵件將有主題行“Log: com.foo.Bar - Hello World” 。默認情況下侣灶,該選項設置為“%logger{20} - %m” 甸祭。 |
discriminator | Discriminator | 在discriminator 的幫助下,SMTPAppender 可以根據(jù)鑒別器返回的值將傳入的事件分散到不同的緩沖區(qū)中褥影。默認識別器總是返回相同的值池户,以便對所有事件使用相同的緩沖區(qū)。通過指定非默認識別器凡怎,可以接收包含與特定用戶校焦、用戶會話或客戶端IP 地址相關的事件的電子郵件消息。 |
evaluator | Ievaluator | 該選項通過創(chuàng)建一個新的<EventEvaluator/> 元素來聲明统倒。需要通過class 屬性指定用戶希望用作SMTPAppender 求值器的類的名稱寨典。在沒有此選項的情況下,SMTPAppender 被分配一個OnErrorEvaluator 實例房匆,該實例在遇到ERROR 級別或更高級別的事件時觸發(fā)電子郵件傳輸耸成。Logback 附帶了其他幾個評估器报亩,即OnMarkerEvaluator (下面討論)和一個名為JaninoEventEvaluator 的強大評估器,將在另一章討論井氢。最新版本的logback 附帶了一個更強大的評估器GEventEvaluator 弦追。 |
cyclicBufferTracker | CyclicBufferTracker | 顧名思義,CyclicBufferTracker 類的一個實例跟蹤循環(huán)緩沖區(qū)毙沾。它是基于識別器返回的鍵來實現(xiàn)的(見上面)骗卜。如果您沒有指定一個cyclicBufferTracker ,那么將自動創(chuàng)建一個CyclicBufferTracker 實例左胞。默認情況下,該實例將事件保存在大小為256 的循環(huán)緩沖區(qū)中举户。您可以在bufferSize 選項的幫助下更改大小(參見下面)烤宙。 |
username | String | 在普通用戶/密碼身份驗證期間使用的用戶名值。默認情況下俭嘁,該參數(shù)為null 躺枕。 |
password | String | 用于普通用戶/密碼身份驗證的密碼值。默認情況下供填,該參數(shù)為null 拐云。 |
STARTTLS | boolean | 如果將該參數(shù)設置為true ,則此附加器將發(fā)出STARTTLS 命令(如果服務器支持該命令)近她,導致連接切換到SSL 叉瘩。注意,連接最初是不加密的粘捎。默認情況下薇缅,該參數(shù)設置為false 。 |
SSL | boolean | 如果將此參數(shù)設置為true 攒磨,則此追加器將打開到服務器的SSL 連接泳桦。默認情況下,該參數(shù)設置為false 娩缰。 |
charsetEncoding | String | 發(fā)出的電子郵件將被編碼在指定的字符集中灸撰。默認的字符集編碼是“UTF-8” ,這在大多數(shù)情況下都能很好地工作拼坎。 |
localhost | String | 如果SMTP 客戶機的主機名沒有正確配置浮毯,例如,如果客戶機主機名沒有完全限定演痒,某些SMTP 服務器可能會拒絕客戶機發(fā)送的HELO/EHLO 命令亲轨。要克服這個問題,可以將localhost 屬性的值設置為客戶機主機的完全限定名鸟顺。參見在com.sun.mail.smtp 包中的“mail.smtp.localhost” 屬性文檔惦蚊。 |
asynchronousSending | boolean | 此屬性確定電子郵件傳輸是否異步完成器虾。默認情況下,異步發(fā)送屬性為“true” 蹦锋。然而兆沙,在某些情況下異步發(fā)送可能是不合適的。例如莉掂,如果應用程序使用SMTPAppender 發(fā)送警報以響應致命錯誤葛圃,然后退出,相關線程可能沒有時間發(fā)送警報電子郵件憎妙。在本例中库正,將用于同步電子郵件傳輸?shù)漠惒桨l(fā)送屬性設置為“false” 。 |
includeCallerData | boolean | 默認情況下厘唾,includeCallerData 被設置為false 褥符。如果啟用了異步發(fā)送,并且希望在日志中包含調(diào)用方數(shù)據(jù)抚垃,則應該將includeCallerData 設置為true 喷楣。 |
sessionViaJNDI | boolean |
SMTPAppende r依賴于javax.mail.Session 發(fā)送電子郵件消息。默認情況下鹤树,sessionViaJNDI 被設置為false 铣焊,因此javax.mail.Session 實例由SMTPAppender 本身使用用戶指定的屬性構建。如果將sessionViaJNDI 屬性設置為true 罕伯,則javax.mail.Session 對象將通過JNDI 檢索曲伊。還請參見jndiLocation 屬性。通過JNDI 檢索Session 可以減少配置/重新配置相同信息所需的位置數(shù)量捣炬,從而使應用程序更加dryer 熊昌。有關在Tomcat 中配置資源的更多信息,請參見JNDI 資源指南湿酸。如該文檔中所述婿屹,在從JNDI 檢索Session 時,請確保從web 應用程序WEB-INF/lib 文件夾中刪除mail.jar 和activation.jar 推溃。 |
jndiLocation | String |
javax.mail.Session 位于JNDI中的位置昂利。默認情況下,jndiLocation 被設置為“java:comp/env/mail/Session” 铁坎。 |
未完待續(xù)蜂奸。。硬萍。