Bug 37904

Summary: AsynchAppender wait for ever when buffer is full
Product: Log4j - Now in Jira Reporter: Jan Kronquist <jan.kronquist>
Component: AppenderAssignee: log4j-dev <log4j-dev>
Status: RESOLVED DUPLICATE    
Severity: normal    
Priority: P2    
Version: 1.2   
Target Milestone: ---   
Hardware: Other   
OS: other   

Description Jan Kronquist 2005-12-14 12:50:14 UTC
When the BoundedFIFO is full the AsynchAppender will wait for ever for the
Dispatcher to remove an element from the buffer. This might seem reasonable as
this will not happen very often, but the following problem occurred in our
production environment:

We wanted to send a mail for certain exceptions. However, the SMTP server was
incorrectly configured which caused the Dispatcher thread to hang for several
minutes for each event. The buffer quickly filled up and then the AsynchAppender
also waited several minutes until all exceptions had been processed.

This was quite difficult to debug since the server seemed to work fine and only
slowed down a while after the error occurred and the file logging worked fine.
We did not realize that the fact that we did not get the email was related to
the server slowing down or hanging. As the server only hang during a couple of
minutes it took a while until we managed to get a thread dump.

The purpose of using AsynchAppender is to avoid blocking the current thread,
therefore I think that the AsynchAppender should handle the buffer full
situation better.

Two different solution proposals:
1) Log something when the buffer is full. This will make this condition easier
to find and will probably only occur in exceptional cases.
2) Limit the time to wait on the buffer. Log and give up when this limit is
exceeded. This will have some extra overhead, but the server will not be blocked
because of incorrect configuration. The timeout should be possible to configure.  

1) Log something when the buffer is full:
      while (bf.isFull()) {
        try {
          LogLog.warn("AsynchAppender buffer is full!!");
          bf.wait();

2) Limit the time to wait on the buffer: 
      long before = System.currentTimeMillis();
      while (bf.isFull()) {
        try {
          //LogLog.debug("Waiting for free space in buffer, "+bf.length());
          bf.wait(this.bufferTimeout);
          if (System.currentTimeMillis()-before >= this.bufferTimeout) {
             LogLog.error("AsynchAppender failed to log event within specified
timeout. event=" + event);
	     return;
          }


(The same problem exists in 1.3)
Comment 1 Curt Arnold 2006-08-31 21:12:39 UTC
AsyncAppender has been rewritten recently to address a large number of issues that we reported against 
it which were rolled into bug 38137 which I'm marking this bug as a duplicate.  In the SVN source for log4j 
1.2 and 1.3, AsyncAppender now has a blocking property that when set to false will cause the appender 
not to block when the queue is full but count and discard messages and to produce a summary when the 
backlog is cleared.  I expect to have new releases with the updated code real-soon-now, but it would be 
most helpful if you could confirm that the new code addresses your concerns before the release.

*** This bug has been marked as a duplicate of 38137 ***