我使用Log4J2"使所有记录器异步"部分设置:
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector.
https://logging.apache.org/log4j/2.x/manual/async.html
我处理了很多日志,然后在退出之前停止了appender:
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并在退出程序之前将剩余的日志写入磁盘。
但接下来会发生什么:
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?
答案 0 :(得分:4)
Log4j2有一个关闭钩子(用于非Web应用程序),它负责等待后台线程处理仍在队列中的任何事件。因此,最好的办法是在仍然使用appender时不要停止它们。让log4j2处理清理工作。
要彻底停止异步记录器,您可以致电org.apache.logging.log4j.core.async.AsyncLogger.stop()
。这将阻塞,直到刷新所有消息。请注意:
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
。