【问题标题】:How to flush Asynchronous loggers in Log4J2 (with disruptor)如何在 Log4J2 中刷新异步记录器(使用中断器)
【发布时间】:2015-05-19 21:42:58
【问题描述】:

我通过设置使用 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();
}

通过这样做,我希望它会在我退出程序之前刷新异步附加程序并将剩余的日志写入磁盘。

但这就是发生的事情:

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

所以关闭看起来并不像实际上正在刷新,并且记录器最终失败。

我的会议:

<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?

【问题讨论】:

    标签: java asynchronous logging configuration log4j2


    【解决方案1】:

    Log4j2 有一个关闭钩子(用于非 Web 应用程序),负责等待后台线程处理仍在队列中的任何事件。所以最好的办法是在 appenders 仍在使用时不要停止它们。让 log4j2 负责清理。

    要彻底停止异步记录器,您可以调用org.apache.logging.log4j.core.async.AsyncLogger.stop()。这会阻塞,直到所有消息都被刷新。请注意:

    • 这仅适用于通过设置“使所有记录器异步”部分: -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector.
    • 您确定要测量这个吗?磁盘 I/O 将主导您的测量。如果要包含 I/O,关闭异步日志记录并测量同步日志记录(包括 I/O)可能更简单。大多数人都对日志记录对其应用程序的影响感兴趣,因此他们只衡量对记录器的调用所花费的时间,而不是将后台线程工作包括在他们的衡量标准中。

    【讨论】:

    • 我不想停止 JVM,我只想刷新消息。我想计算为基准测试记录消息所花费的时间,所以我不能直接退出。
    • 消息会自动刷新。通过 JMX,您可以监控 RingBuffer 是否为空。
    • 如果没有办法做到这一点也没关系,但让我们弄清楚。
    • @gaurav 否。无论 appender 和 loggers 是如何创建的,在它们仍在使用时都不应该停止它们。应用程序不知道 Log4j 队列中是否还有工作。 Log4j2 有一个关闭钩子(用于非 Web 应用程序),负责等待后台线程处理仍在队列中的任何事件。让 log4j2 负责清理。
    • 这个答案已经过时了。没有org.apache.logging.log4j.core.async.AsyncLogger.stop()方法logging.apache.org/log4j/2.x/log4j-core/apidocs/org/apache/…
    猜你喜欢
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多