2015-05-19 80 views
3

我使用Log4J2「製作的所有記錄異步」部分刷新異步伐木工人在Log4J2(與干擾物):如何通過設置

-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector. 

https://logging.apache.org/log4j/2.x/manual/async.html

我處理大量的日誌,然後停止退出前追加程序:

org.apache.logging.log4j.core.Logger coreLogger = (org.apache.logging.log4j.core.Logger) logger; 
org.apache.logging.log4j.core.LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) coreLogger.getContext(); 
Map<String, Appender> appenders = context.getConfiguration().getAppenders(); 
for (Appender appender : appenders.values()) { 
    appender.stop(); 
} 

通過這樣做,我希望這將刷新異步的appender(S)和寫入磁盤剩餘日誌之前,我退出程序。

但這裏是發生了什麼:

2015-05-19 14:09:58,540 ERROR Attempted to append to non-started appender myFileAppender 
Exception in thread "AsyncLogger-1" java.lang.RuntimeException: org.apache.logging.log4j.core.appender.AppenderLoggingException: Attempted to append to non-started appender myFileAppender 
    at com.lmax.disruptor.FatalExceptionHandler.handleEventException(FatalExceptionHandler.java:45) 
    at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:147) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.apache.logging.log4j.core.appender.AppenderLoggingException: Attempted to append to non-started appender myFileAppender 
    at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:89) 
    at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:430) 
    at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:409) 
    at org.apache.logging.log4j.core.Logger$PrivateConfig.logEvent(Logger.java:288) 
    at org.apache.logging.log4j.core.async.AsyncLogger.actualAsyncLog(AsyncLogger.java:305) 
    at org.apache.logging.log4j.core.async.RingBufferLogEvent.execute(RingBufferLogEvent.java:100) 
    at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:43) 
    at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:28) 
    at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:128) 
    ... 3 more 

所以密切看起來並不像它實際上衝洗和記錄器最終失敗。

我的conf:

<Configuration> 
    <Appenders> 
    <RollingFile name="myFileAppender" fileName="/tmp/test.log" ignoreExceptions="false" immediateFlush="false"> 
     <PatternLayout><Pattern>%m%n</Pattern></PatternLayout> 
     <Policies> 
     <TimeBasedTriggeringPolicy /> 
     </Policies> 
    </RollingFile> 
    <Console name="STDOUT"> 
     <PatternLayout pattern="%C{1.} %m %level MDC%X%n"/> 
    </Console> 
    </Appenders> 

    <Loggers> 
    <Logger name="myLogger" level="info" additivity="false"> 
     <AppenderRef ref="myFileAppender" /> 
    </Logger> 
    <Root level="fatal"> 
     <AppenderRef ref="STDOUT"/> 
    </Root> 
    </Loggers> 
</Configuration> 

我怎麼能刷新/同步log4j2?

回答

1

Log4j2有一個關閉掛鉤(用於非web應用程序),負責等待後臺線程處理仍在隊列中的任何事件。所以最好的辦法是在他們還在使用時不要阻止appender。讓log4j2負責清理。

要乾淨地停止異步記錄器,可以撥打org.apache.logging.log4j.core.async.AsyncLogger.stop()。這會阻塞,直到所有消息都被刷新。注意:

  • 這僅當「使所有記錄異步」部分作品設置: -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
  • 您確定要評估這個嗎?磁盤I/O將主導您的測量。如果你想包含I/O,關閉異步記錄和測量同步記錄(包括I/O)可能會更簡單。大多數人都對登錄應用程序的影響感興趣,所以他們只測量對記錄器的調用所花費的時間,並且不在測量中包含後臺線程工作。
+1

我不想停止JVM,但我只想刷新消息。我想計算爲基準測試記錄消息需要多少時間,所以我不能退出。 – bananasplit

+0

消息自動刷新。通過JMX,您可以監視RingBuffer是否爲空。 –

+0

如果沒有辦法做到這一點很好,但讓我們清楚。 – bananasplit