log4j2之日誌記錄器
log4j2之日誌記錄器
詳見官網配置說明: https://logging.apache.org/log4j/2.x/manual/async.html
1. 使所有記錄器異步
Log4j-2.9及更高版本在類路徑上需要disruptor-3.3.4.jar或更高版本。在Log4j-2.9之前,需要disruptor-3.0.0.jar或更高版本。
這是最簡單的配置,並提供最佳性能。要使所有記錄器異步,請將disruptor jar添加到類路徑,並將系統屬性log4j2.contextSelector設置 為org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
默認情況下,異步記錄器不會將位置傳遞給I / O線程。如果您的某個布局或自定義過濾器需要位置信息,則需要在所有相關記錄器的配置中設置“includeLocation = true”,包括根記錄器。
不需要位置的配置可能如下所示:
<!-- Don‘t forget to set system property
-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
to make all loggers asynchronous. --
<?xml version="1.0" encoding="UTF-8"?>
<!-- Don‘t forget to set system property
- -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
- to make all loggers asynchronous. -->
- <Configuration status="WARN">
- <Appenders>
- <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
- <RandomAccessFile name="RandomAccessFile" fileName="async.log" immediateFlush="false" append="false">
- <PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
- </PatternLayout>
- </RandomAccessFile>
- </Appenders>
- <Loggers>
- <Root level="info" includeLocation="false">
- <AppenderRef ref="RandomAccessFile"/>
- </Root>
- </Loggers>
- </Configuration>
當使用AsyncLoggerContextSelector使所有記錄器異步時,請確保在配置中使用普通的 <root>和<logger>元素。AsyncLoggerContextSelector將確保所有記錄器都是異步的,使用的機制與配置<asyncRoot> 或<asyncLogger>時所發生的機制不同。後面的元素用於將異步與同步記錄器混合。如果同時使用這兩種機制,最終會有兩個後臺線程,應用程序將日誌消息傳遞給線程A,線程A將消息傳遞給線程B,線程B最後將消息記錄到磁盤。這是有效的,但中間會有一個不必要的步驟。
您可以使用一些系統屬性來控制異步日誌記錄子系統的各個方面。其中一些可用於調整日誌記錄性能。
還可以通過創建名為log4j2.component.properties的文件並在應用程序的類路徑中包含此文件來指定以下屬性 。
請註意,系統屬性在Log4j 2.10.0中重命名為更一致的樣式。此處還記錄了所有舊屬性名稱。
系統屬性 | 默認值 | 描述 |
---|---|---|
log4j2.asyncLoggerExceptionHandler | 默認處理程序 | 實現com.lmax.disruptor.ExceptionHandler 接口的類的完全限定名稱。該類需要有一個公共零參數構造函數。如果指定,則在記錄消息時發生異常時將通知此類。
如果未指定,則缺省異常處理程序將打印消息並將堆棧跟蹤寫入標準錯誤輸出流。 |
log4j2.asyncLoggerRingBufferSize | 256 * 1024 | 異步日誌記錄子系統使用的RingBuffer中的大小(插槽數)。使此值足夠大以處理突發的活動。最小大小為128. RingBuffer將在首次使用時預先分配,並且在系統生命周期內不會增長或縮小。
當應用程序的記錄速度快於底層appender可以跟上足夠長的時間來填充隊列時,行為由AsyncQueueFullPolicy決定 。 |
log4j2.asyncLoggerWaitStrategy | 超時 | 有效值:Block,Timeout,Sleep,Yield。 Block是一種策略,它使用鎖和條件變量來等待I / O線程等待日誌事件。當吞吐量和低延遲不如CPU資源那麽重要時,可以使用塊。建議用於資源受限/虛擬化環境。 超時是塊策略的變體,它將定期從鎖定條件await()調用中喚醒。這確保了如果錯過通知,消費者線程不會卡住,但會以較小的延遲延遲(默認為10毫秒)恢復。 睡覺是一種最初旋轉的策略,然後使用Thread.yield(),並最終停止操作系統和JVM在I / O線程等待日誌事件時允許的最小數量的nanos。睡眠是性能和CPU資源之間的良好折衷。此策略對應用程序線程的影響非常小,以換取實際獲取消息的一些額外延遲。 Yield是一種策略,它使用Thread.yield()在最初旋轉之後等待日誌事件。Yield是性能和CPU資源之間的良好折衷,但可能會使用比Sleep更多的CPU,以便更快地將消息記錄到磁盤。 |
log4j2.asyncLoggerThreadNameStrategy | CACHED |
有效值:CACHED,UNCACHED。
默認情況下,AsyncLogger將線程名稱緩存在ThreadLocal變量中以提高性能。如果應用程序在運行時修改線程名稱(使用Thread.currentThread()。setName())並且您希望在日誌中看到新的線程名稱,請指定UNCACHED選項 。 |
log4j2.clock | SystemClock |
org.apache.logging.log4j.core.util.Clock
接口的
實現,用於在所有記錄器異步時為日誌事件添加時間戳。
CachedClock是一種針對低延遲應用程序的優化,其中時鐘戳是從時鐘生成的,該時鐘在後臺線程中每毫秒或每1024個日誌事件更新其內部時間,以先到者為準。這會略微降低日誌記錄延遲,但會以記錄時間戳的某些精度為代價。除非您記錄了許多事件,否則您可能會在日誌時間戳之間看到10-16毫秒的“跳躍”。WEB應用程序警告:使用後臺線程可能會導致Web應用程序和OSGi應用程序出現問題,因此不建議將CachedClock用於此類應用程序。 您還可以指定實現Clock接口的自定義類的完全限定類名 。 |
混合同步和異步記錄器
Log4j-2.9及更高版本在類路徑上需要disruptor-3.3.4.jar或更高版本。在Log4j-2.9之前,需要disruptor-3.0.0.jar或更高版本。無需將系統屬性“Log4jContextSelector”設置為任何值。
可以在配置中組合同步和異步記錄器。這為您提供了更大的靈活性,但代價是性能略有下降(與使所有記錄器異步相比)。使用<asyncRoot>或<asyncLogger> 配置元素指定需要異步的記錄器。配置只能包含一個根記錄器(<root> 或<asyncRoot>元素),但是可以組合異步和非異步記錄器。例如,包含<asyncLogger>元素的配置文件也可以包含<root>和 < 同步記錄器的元素。
默認情況下,異步記錄器不會將位置傳遞給I / O線程。如果您的某個布局或自定義過濾器需要位置信息,則需要在所有相關記錄器的配置中設置“includeLocation = true”,包括根記錄器。
混合異步記錄器的配置可能如下所示:
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- No need to set system property "log4j2.contextSelector" to any value
- when using <asyncLogger> or <asyncRoot>. -->
- <Configuration status="WARN">
- <Appenders>
- <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
- <RandomAccessFile name="RandomAccessFile" fileName="asyncWithLocation.log"
- immediateFlush="false" append="false">
- <PatternLayout>
- <Pattern>%d %p %class{1.} [%t] %location %m %ex%n</Pattern>
- </PatternLayout>
- </RandomAccessFile>
- </Appenders>
- <Loggers>
- <!-- pattern layout actually uses location, so we need to include it -->
- <AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true">
- <AppenderRef ref="RandomAccessFile"/>
- </AsyncLogger>
- <Root level="info" includeLocation="true">
- <AppenderRef ref="RandomAccessFile"/>
- </Root>
- </Loggers>
- </Configuration>
您可以使用一些系統屬性來控制異步日誌記錄子系統的各個方面。其中一些可用於調整日誌記錄性能。
還可以通過創建名為log4j2.component.properties的文件並在應用程序的類路徑中包含此文件來指定以下屬性 。
請註意,系統屬性在Log4j 2.10中重命名為更一致的樣式。此處還記錄了所有舊屬性名稱。
系統屬性 | 默認值 | 描述 |
---|---|---|
log4j2.asyncLoggerConfigExceptionHandler | 默認處理程序 |
實現com.lmax.disruptor.ExceptionHandler
接口的類的完全限定名稱。該類需要有一個公共零參數構造函數。如果指定,則在記錄消息時發生異常時將通知此類。
如果未指定,則缺省異常處理程序將打印消息並將堆棧跟蹤寫入標準錯誤輸出流。 |
log4j2.asyncLoggerConfigRingBufferSize | 256 * 1024 |
異步日誌記錄子系統使用的RingBuffer中的大小(插槽數)。使此值足夠大以處理突發的活動。最小大小為128. RingBuffer將在首次使用時預先分配,並且在系統生命周期內不會增長或縮小。
當應用程序的記錄速度快於底層appender可以跟上足夠長的時間來填充隊列時,行為由AsyncQueueFullPolicy決定 。 |
log4j2.asyncLoggerConfigWaitStrategy | 超時 |
有效值:Block,Timeout,Sleep,Yield。
Block是一種策略,它使用鎖和條件變量來等待I / O線程等待日誌事件。當吞吐量和低延遲不如CPU資源那麽重要時,可以使用塊。建議用於資源受限/虛擬化環境。 超時是塊策略的變體,它將定期從鎖定條件await()調用中喚醒。這確保了如果錯過通知,消費者線程不會卡住,但會以較小的延遲延遲(默認為10毫秒)恢復。 睡覺是一種最初旋轉的策略,然後使用Thread.yield(),並最終停止操作系統和JVM在I / O線程等待日誌事件時允許的最小數量的nanos。睡眠是性能和CPU資源之間的良好折衷。此策略對應用程序線程的影響非常小,以換取實際獲取消息的一些額外延遲。 Yield是一種策略,它使用Thread.yield()在最初旋轉之後等待日誌事件。Yield是性能和CPU資源之間的良好折衷,但可能會使用比Sleep更多的CPU,以便更快地將消息記錄到磁盤。 |
log4j2之日誌記錄器