Java 如何刷新Log4J2中的异步记录器(带中断器)

Java 如何刷新Log4J2中的异步记录器(带中断器),java,asynchronous,logging,configuration,log4j2,Java,Asynchronous,Logging,Configuration,Log4j2,我使用Log4J2“使所有记录器异步”部分,设置: -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector. 我处理大量日志,然后在退出之前停止附加程序: org.apache.logging.log4j.core.Logger coreLogger = (org.apache.logging.log4j.core.Logger) logger; org.apache.logg

我使用Log4J2“使所有记录器异步”部分,设置:

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

我处理大量日志,然后在退出之前停止附加程序:

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();
}
因此,关闭看起来不像是实际刷新,记录器最终失败

我的确认:

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

%m%n

如何刷新/同步log4j2?

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)可能会更简单。大多数人都对日志记录对应用程序的影响感兴趣,因此他们只测量对日志记录程序的调用需要多长时间,而不在测量中包括后台线程的工作

但我不想停止JVM,我只想刷新消息。我想计算记录一个基准测试的消息需要多少时间,这样我就不能直接退出了。消息会自动刷新。通过JMX,您可以监视RingBuffer是否为空。如果没有办法,这很好,但让我们澄清一下。谢谢,这看起来就像我在停止正在使用的记录器的所有附加器时尝试执行的操作。你知道我为什么会出现异常吗?@gaurav不知道。无论Appender和Logger是如何创建的,当它们仍在使用时都不应该停止。应用程序不知道Log4j在队列中是否还有工作。Log4j2有一个关闭钩子(对于非web应用程序),负责等待后台线程处理队列中的任何事件。让log4j2负责清理。
<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>