title: How to flush Asynchronous loggers in Log4J2 (with disruptor)
body: <p>I'm using Log4J2 "Making All Loggers Asynchronous" section by setting:</p>
  
  <pre><code>-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector.
  </code></pre>
  
  <p><a href="https://logging.apache.org/log4j/2.x/manual/async.html" rel="noreferrer">https://logging.apache.org/log4j/2.x/manual/async.html</a></p>
  
  <p>I process a lot of logs and then stop the appenders before exiting:</p>
  
  <pre><code>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&lt;String, Appender&gt; appenders = context.getConfiguration().getAppenders();
  for (Appender appender : appenders.values()) {
    appender.stop();
  }
  </code></pre>
  
  <p>By doing so I'm hoping that it will flush the async appender(s) and write to the disk the remaining logs before I exit the program.</p>
  
  <p>But here is what happens:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>So the close doesn't look like it's actually flushing and the logger ends up failing.</p>
  
  <p>My conf:</p>
  
  <pre><code>&lt;Configuration&gt;
    &lt;Appenders&gt;
      &lt;RollingFile name="myFileAppender" fileName="/tmp/test.log" ignoreExceptions="false" immediateFlush="false"&gt;
        &lt;PatternLayout&gt;&lt;Pattern&gt;%m%n&lt;/Pattern&gt;&lt;/PatternLayout&gt;
        &lt;Policies&gt;
          &lt;TimeBasedTriggeringPolicy /&gt;
        &lt;/Policies&gt;
      &lt;/RollingFile&gt;
      &lt;Console name="STDOUT"&gt;
        &lt;PatternLayout pattern="%C{1.} %m %level MDC%X%n"/&gt;
      &lt;/Console&gt;
    &lt;/Appenders&gt;
  
    &lt;Loggers&gt;
      &lt;Logger name="myLogger" level="info" additivity="false"&gt;
        &lt;AppenderRef ref="myFileAppender" /&gt;
      &lt;/Logger&gt;
      &lt;Root level="fatal"&gt;
        &lt;AppenderRef ref="STDOUT"/&gt;
      &lt;/Root&gt;
    &lt;/Loggers&gt;
  &lt;/Configuration&gt;
  </code></pre>
  
  <p>How can I flush / synchronize log4j2?</p>