Log4j2異步日誌
異步日誌
log4j2最大的特點就是異步日誌,其性能的提升主要也是從異步日誌中受益,我們來看看如何使用log4j2的異步日誌。
同步日誌
異步日誌
Log4j2提供了兩種實現日誌的方式,一個是通過AsyncAppender,一個是通過AsyncLogger,分別對應前面我們說的Appender組件和Logger組件。
注意:配置異步日誌需要添加依賴
<!--異步日誌依賴-->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.4</version>
</dependency>
1. AsyncAppender方式
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<properties>
<property name="LOG_HOME">D:/logs</property>
</properties>
<Appenders>
<File name="file" fileName="${LOG_HOME}/myfile.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</File>
<Async name="Async">
<AppenderRef ref="file"/>
</Async>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Async"/>
</Root>
</Loggers>
</Configuration
2. AsyncLogger方式
AsyncLogger纔是log4j2 的重頭戲,也是官方推薦的異步方式。它可以使得調用Logger.log返回的更快。你可以有兩種選擇:全局異步和混合異步。
全局異步就是,所有的日誌都異步的記錄,在配置文件上不用做任何改動,只需要添加一個log4j2.component.properties 配置;
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
混合異步就是,你可以在應用中同時使用同步日誌和異步日誌,這使得日誌的配置方式更加靈活。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<properties>
<property name="LOG_HOME">D:/logs</property>
</properties>
<Appenders>
<File name="file" fileName="${LOG_HOME}/myfile.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</File>
<Async name="Async">
<AppenderRef ref="file"/>
</Async>
</Appenders>
<Loggers>
<AsyncLogger name="com.leon" level="trace" includeLocation="false" additivity="false">
<AppenderRef ref="file"/>
</AsyncLogger>
<Root level="info" includeLocation="true">
<AppenderRef ref="file"/>
</Root>
</Loggers>
</Configuration>
如上配置: com.leon日誌是異步的,root日誌是同步的。
使用異步日誌需要注意的問題:
1. 如果使用異步日誌,AsyncAppender、AsyncLogger和全局日誌,不要同時出現。性能會和AsyncAppender一致,降至最低。
2. 設置includeLocation=false ,打印位置信息會急劇降低異步日誌的性能,比同步日誌還要慢。
<?xml version="1.0" encoding="UTF-8"?>
<!--
status="warn" 日誌框架本身的輸出日誌級別
monitorInterval="5" 自動加載配置文件的間隔時間,不低於 5 秒
-->
<Configuration status="debug" monitorInterval="5">
<!--
集中配置屬性進行管理
使用時通過:${name}
-->
<properties>
<property name="LOG_HOME">/logs</property>
</properties>
<!--日誌處理-->
<Appenders>
<!--控制檯輸出 appender-->
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n" />
</Console>
<!--日誌文件輸出 appender-->
<File name="file" fileName="${LOG_HOME}/myfile.log">
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %c{36} - %m%n" />
</File>
<!--<Async name="Async">-->
<!--<AppenderRef ref="file"/>-->
<!--</Async>-->
<!--使用隨機讀寫劉的日誌文件輸出 appender,性能提高-->
<RandomAccessFile name="accessFile" fileName="${LOG_HOME}/myAcclog.log">
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %c{36} - %m%n" />
</RandomAccessFile>
<!--按照一定規則拆分的日誌文件的 appender-->
<RollingFile name="rollingFile" fileName="${LOG_HOME}/myrollog.log"
filePattern="/logs/$${date:yyyy-MM-dd}/myrollog-%d{yyyy-MM-dd-HH-mm}-%i.log">
<!--日誌級別過濾器-->
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" />
<!--日誌消息格式-->
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %c{36} - %msg%n" />
<Policies>
<!--在系統啓動時,出發拆分規則,生產一個新的日誌文件-->
<OnStartupTriggeringPolicy />
<!--按照文件大小拆分,10MB -->
<SizeBasedTriggeringPolicy size="10 MB" />
<!--按照時間節點拆分,規則根據filePattern定義的-->
<TimeBasedTriggeringPolicy />
</Policies>
<!--在同一個目錄下,文件的個數限定爲 30 個,超過進行覆蓋-->
<DefaultRolloverStrategy max="30" />
</RollingFile>
</Appenders>
<!--logger 定義-->
<Loggers>
<!--自定義異步 logger 對象
includeLocation="false" 關閉日誌記錄的行號信息
additivity="false" 不在繼承 rootlogger 對象
-->
<AsyncLogger name="com.leon" level="trace" includeLocation="false" additivity="false">
<AppenderRef ref="Console"/>
</AsyncLogger>
<!--使用 rootLogger 配置 日誌級別 level="trace"-->
<Root level="trace">
<!--指定日誌使用的處理器-->
<AppenderRef ref="Console" />
<!--使用異步 appender-->
<AppenderRef ref="Async" />
</Root>
</Loggers>
</Configuration>
記錄峯值吞吐量
下圖比較了同步記錄器,異步附加器和異步記錄器的吞吐量。這是所有線程在一起的總吞吐量。在具有64個線程的測試中,異步記錄器比異步附加器快12倍,比同步記錄器快68倍。
異步記錄器的吞吐量隨線程數的增加而增加,而同步記錄器和異步附加程序都具有或多或少的恆定吞吐量,而與執行記錄的線程數無關。
與其他日誌記錄包的異步吞吐量比較
我們還將異步記錄器的峯值吞吐量與其他日誌記錄包(尤其是log4j-1.2.17和logback-1.0.10)中可用的同步記錄器和異步附加程序進行了比較,結果相似。對於異步附加程序,添加更多線程時,所有線程的總日誌記錄吞吐量大致保持不變。在多線程方案中,異步記錄器可以更有效地利用計算機上可用的多個內核。
Log4j2的性能
Log4j2最牛的地方在於異步輸出日誌時的性能表現,Log4j2在多線程的環境下吞吐量與Log4j和Logback的比較如下圖。下圖比較中Log4j2有三種模式:
1)全局使用異步模式;
2)部分Logger採用異步模式;
3)異步Appender。可以看出在前兩種模式下,Log4j2的性能較之Log4j和Logback有很大的優勢。