溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

log4j2異步日志輸出方式有幾種

發(fā)布時間:2021-12-22 12:49:17 來源:億速云 閱讀:1657 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下log4j2異步日志輸出方式有幾種,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

log4j2的異步日志輸出方式

使用log4j2的同步日志進(jìn)行日志輸出,日志輸出語句與程序的業(yè)務(wù)邏輯語句將在同一個線程運行。

而使用異步日志進(jìn)行輸出時,日志輸出語句與業(yè)務(wù)邏輯語句并不是在同一個線程中運行,而是有專門的線程用于進(jìn)行日志輸出操作,處理業(yè)務(wù)邏輯的主線程不用等待即可執(zhí)行后續(xù)業(yè)務(wù)邏輯。

Log4j2中的異步日志實現(xiàn)方式有AsyncAppender和AsyncLogger兩種。

其中:

  • AsyncAppender采用了ArrayBlockingQueue來保存需要異步輸出的日志事件;

  • AsyncLogger則使用了Disruptor框架來實現(xiàn)高吞吐。

第一種實現(xiàn)異步方式AsyncAppender

AsyncAppender直接在log4j2的xml的配置文件中配置,注意下面代碼的注釋位置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
  <Appenders>
    <!--正常的Appender配置,此處配置的RollingFile會在下面AsyncAppender被通過name引用-->
    <RollingFile name="RollingFileError" fileName="${Log_Home}/error.${date:yyyy-MM-dd}.log" immediateFlush="true"
filePattern="${Log_Home}/$${date:yyyy-MM}/error-%d{MM-dd-yyyy}-%i.log.gz">
     <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %logger{36} : %msg%xEx%n"/>
     <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
     <Policies>
                <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
                <SizeBasedTriggeringPolicy size="10MB"/>
     </Policies>
   </RollingFile>
    <!--一個Appender配置完畢-->
    <!--異步AsyncAppender進(jìn)行配置直接引用上面的RollingFile的name-->
    <Async name="Async">
      <AppenderRef ref="MyFile"/>
    </Async>
    <!--異步AsyncAppender配置完畢,需要幾個配置幾個-->
  </Appenders>
  <Loggers>
    <Root level="error">
      <!--此處如果引用異步AsyncAppender的name就是異步輸出日志-->
      <!--此處如果引用Appenders標(biāo)簽中RollingFile的name就是同步輸出日志-->
      <AppenderRef ref="Async"/>
    </Root>
  </Loggers>
</Configuration>

重點內(nèi)容全在上面代碼的注釋中,AsyncAppender的配置就在xml文件中實現(xiàn),無需單獨引用包來支持.配置AsyncAppender后,日志事件寫入文件的操作將在單獨的線程中執(zhí)行。

AsyncAppender的常用參數(shù)

參數(shù)名類型說明
nameStringAsync Appender的名字
AppenderRefString異步調(diào)用的Appender的名字,可以配置多個
blockingboolean默認(rèn)為true。如果為true,appender將一直等待直到queue中有空閑;如果為false,當(dāng)隊列滿的時候,日志事件將被丟棄。(如果配置了error appender,要丟棄的日志事件將由error appender處理)
bufferSizeinteger隊列中可存儲的日志事件的最大數(shù)量,默認(rèn)為128

第二種實現(xiàn)異步方式AsyncLogger

Log4j2中的AsyncLogger的內(nèi)部使用了Disruptor框架。

Disruptor簡介

Disruptor是英國外匯交易公司LMAX開發(fā)的一個高性能隊列,基于Disruptor開發(fā)的系統(tǒng)單線程能支撐每秒600萬訂單。

目前,包括Apache Strom、Log4j2在內(nèi)的很多知名項目都應(yīng)用了Disruptor來獲取高性能。

Disruptor框架內(nèi)部核心數(shù)據(jù)結(jié)構(gòu)為RingBuffer,其為無鎖環(huán)形隊列。

Disruptor為什么這么快?

  • lock-free-使用了CAS來實現(xiàn)線程安全

  • 使用緩存行填充解決偽共享問題

首先在pom單中應(yīng)用相關(guān)的包

<dependency>
  <groupId>com.lmax</groupId>
  <artifactId>disruptor</artifactId>
  <version>3.4.2</version>
</dependency>

第二步在log4j2的xml文件中配置AsyncLogger

log4j2.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="MyApp" packages="">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
        <RollingFile name="RollingFile" fileName="logs/app.log"
                     filePattern="logs/app-%d{yyyy-MM-dd HH}.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <SizeBasedTriggeringPolicy size="500MB"/>
            </Policies>
        </RollingFile>
        <RollingFile name="RollingFile2" fileName="logs/app2.log"
                     filePattern="logs/app2-%d{yyyy-MM-dd HH}.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <SizeBasedTriggeringPolicy size="500MB"/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
    <!--上面的配置都和原配置一樣,就是在下方這直接定義AsyncLogger,他的name在java類中被引用即可-->
        <AsyncLogger name="com.meituan.Main" level="trace" additivity="false">
            <appender-ref ref="RollingFile"/>
        </AsyncLogger>
        <AsyncLogger name="RollingFile2" level="trace" additivity="false">
            <appender-ref ref="RollingFile2"/>
        </AsyncLogger>
        <Root level="debug">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>

java代碼如下:

public class Main {
    public static void main(String args[]) {
        //引用com.meituan.Main日志輸出器
        Logger logger = LogManager.getLogger(Main.class);
        //引用的名為RollingFile2的異步AsyncLogger
        Logger logger2 = LogManager.getLogger("RollingFile2");
        Person person = new Person("Li", "lei");
        logger.info("hello, {}", person);
        logger2.info("good bye, {}", person);
}

上述log4j2.xml中配置了兩個AsyncLogger,名字分別為com.meituan.Main和RollingFile2。

并且,在main方法中分別使用兩個logger來輸出兩條日志。

在加載log4j2.xml的啟動階段,如果檢測到配置了AsyncRoot或AsyncLogger,將啟動一個disruptor實例。

log4j2異步注意事項

log4j2異步類型

1) 使用<Async>標(biāo)簽

示例:

<Async name="asyncKafkaLog">
    <AppenderRef ref="Failover" />
</Async>

注意事項: 此類異步隊列是BockingQueue,隊列默認(rèn)大小是128

2) 使用<AsyncLogger>標(biāo)簽

示例:

<AsyncLogger name="kafkaLogger" level="trace" includeLocation="false">
    <AppenderRef ref="Failover"/>
</AsyncLogger>

注意事項: 此類異步隊列是Disruptor隊列默認(rèn)大小是4096

3) 使用 JVM參數(shù)

示例:

#啟動參數(shù)方式
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
#代碼方式
System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");

注意事項: 此類異步是全量異步,log4j配置文件里所有l(wèi)ogger都自動異步,使用異步隊列為Disruptor,隊列默認(rèn)大小4096

小提示

① Disruptor隊列性能遠(yuǎn)勝于BlockingQueue,這也是log4j2性能提升的重要原因之一

② 如果啟用了全量異步,又使用了<AsyncLogger>會如何?

  • log4j2會新建兩個Disruptor隊列,<AsyncLogger>之流使用一個,其他的使用另外一個,所以建議將可能發(fā)生阻塞的logger歸類使用一個Disruptor,畢竟是隊列,一個阻塞了其他的得乖乖等著

③ 如果默認(rèn)隊列長度不足咋辦?

#第一步:加大兩個Disruptor隊列的長度
-DAsyncLogger.RingBufferSize=262144
-DAsyncLoggerConfig.RingBufferSize=262144  
#第二步:設(shè)置隊列滿了時的處理策略:丟棄,否則默認(rèn)blocking,異步就與同步無異了
-Dlog4j2.AsyncQueueFullPolicy=Discard

以上是“l(fā)og4j2異步日志輸出方式有幾種”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI