user755806
user755806

Reputation: 6815

Log4j Async appender usage?

I am using log4j AsyncAppender. i wrote my own appender to customise the logger as below.

public class MyAppender extends AppenderSkeleton {

@Override
public void close() {

}


@Override
public boolean requiresLayout() {
    return false;
}


@Override
protected void append(LoggingEvent event) {

//Here am doing some logic which will connect database and fetch some records.  

}

}

My log4j configuration:

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">

    <!-- Appenders -->

    <appender name="stdout" class="com.sample.MyAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %p [%c] - %m%n"/>
        </layout>
    </appender>


    <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="500"/>
        <appender-ref ref="stdout"/>
    </appender>


    <root>
        <level value="INFO" />
        <appender-ref ref="ASYNC" />
    </root>

</log4j:configuration>

Now everything works fine. Im MyAppender i will fire a Select query and fetch some details from the table and send those details using java mail API. As i am using AsyncAppender, it does not block existing running thread and the MyAppender logic is executed Asynchronously.My question is if the main thread completes its execution before MyAppender logic gets completed then is there any guarantee that the logic in MyAppender will be completed even if main thread completes its execution?

Thanks!

Upvotes: 2

Views: 5807

Answers (2)

Mike Monette
Mike Monette

Reputation: 640

It's been a year, but I'll answer for the benefit of others after me. The proper way to safely close all appenders and ensure that your JVM doesn't shut down before logging is complete is to call LogManager.shutdown();. I haven't confirmed, but this is apparently not necessary in Log4j 2, since it registers a shutdown hook with the JVM automatically.

Upvotes: 2

dcernahoschi
dcernahoschi

Reputation: 15230

Just thrown a quick look at the AsyncAppender class source code. It seems that the thread that asynchronously process the logging events is set as a daemon thread. So when the main thread exits the logging thread exits too, possibly with unhandled logging requests in the queue.

There is also a comment above the setDaemon(true) call: It is the user's responsibility to close appenders before exiting. (meaning that upon closing the logger thread will complete its queued logging events, see the close() method code snippet)

  public  AsyncAppender() {
    appenders = new AppenderAttachableImpl();
    aai = appenders;
    dispatcher =  new Thread(new Dispatcher(this, buffer, discardMap, appenders));

    // It is the user's responsibility to close appenders before
    // exiting.
    dispatcher.setDaemon(true);


    // set the dispatcher priority to lowest possible value
    //        dispatcher.setPriority(Thread.MIN_PRIORITY);
    dispatcher.setName("AsyncAppender-Dispatcher-" + dispatcher.getName());
    dispatcher.start();
  }



    //Close this AsyncAppender by interrupting the dispatcher 
    //thread which will process all pending events before exiting.
  public void  close() {
    ...

     try {
      dispatcher.join();
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      org.apache.log4j.helpers.LogLog.error(
        "Got an InterruptedException while waiting for the "
                        + "dispatcher to finish.", e);
    }
    ...
  }

Upvotes: 0

Related Questions