[
https://issues.apache.org/jira/browse/LOG4J2-927?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14565105#comment-14565105
]
Mariano Gonzalez commented on LOG4J2-927:
-----------------------------------------
I've been trying to get a unit test to reproduce the issue but I haven't been
able to. My project is an application server and this issue happens when
deployment of an application fails, so reproducing all the moving parts into a
junit test (classloaders hierarchies, lifecycle, etc) is really hard.
What I noticed is that the algorithm than Remko mentioned is implemented in
org.apache.logging.log4j.core.async.AsyncLogger#stop(), which is only invoked
by org.apache.logging.log4j.core.async.AsyncLoggerContext#stop().
However, if like in my case, you're using async loggers with a regular
LoggerContext, then you get an implementation that eventually delegates into
AbstractConfiguration#stop(), which first stops the async loggers, then the
root loggers, then the appenders and finally the synchronous loggers. This
makes room for the issue I'm experiencing in which by the time disruptor
executes the logging event, the context has already been stopped.
Please let me know if any of this makes sense or I'm way off.
Thanks!
> Race condition between a LoggerContext stop() and async loggers
> ---------------------------------------------------------------
>
> Key: LOG4J2-927
> URL: https://issues.apache.org/jira/browse/LOG4J2-927
> Project: Log4j 2
> Issue Type: Bug
> Components: Appenders
> Affects Versions: 2.1
> Reporter: Mariano Gonzalez
>
> I have an application in which I'm using all async loggers. When I stop the
> LoggerContext, there're still some events waiting in disruptor's buffer and
> when it tries to execute them the context is already closed and thus those
> events are lost. In the case of a RollingFileAppender, I get an IOException
> because the outputStream has already been closed.
> As a debugging technique, I did an Appedder decorator that looks like this:
> {code:java}
> final class StopConditionSafeAppenderWrapper extends BaseAppenderWrapper
> {
> private final LoggerContext loggerContext;
> StopConditionSafeAppenderWrapper(Appender delegate, LoggerContext
> loggerContext)
> {
> super(delegate);
> this.loggerContext = loggerContext;
> }
> @Override
> public void append(LogEvent event)
> {
> if (!loggerContext.isStarted()) {
> return;
> }
> super.append(event);
> }
> }
> {code}
> With the help of a debugger, I could verify that when the append method was
> invoked the loggerContext was started but then by the time the exception
> occurred it was closed.
> It checked the code at LoggerContext#stop() and saw that there's code to
> prevent disruptor from taking new events once a stop() has been invoked, but
> there's no code to wait for the ring buffer to be fully consumed before
> actually stopping.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]