Search code examples
javalogginglog4jjava-ee-6

Writing own appender by extending AppenderSkeleton?


I am using log4j AsyncAppender. I wrote my own appender to customize 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.
        // This process might take few seconds  

    }

}

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 parent thread and the MyAppender logic is executed Asynchronously using separate thread.My question is if the parent thread completes its execution before MyAppender logic gets completed then is there any guarantee that the logic in MyAppender will be completed even if parent thread completes its execution?

My application will be deployed on Tomcat.

Thanks!


Solution

  • This is fine, the AsyncAppender has its own thread for handling this case. Your appender does not have to complete before the thread that generated the message completes. Once your appender gets the message, it is in another thread entirely. At this point the appender does not know or care about the parent. One could argue that this use case is the reason the AsyncAppender class exists at all.

    If you like, you can check it out for yourself.

    A way you can test this yourself is to make an AsyncAppender that sleeps for a very long time (say 10 seconds) before logging something. Log something to the appender in your parent thread and watch it go to the appender. You should see your parent thread "end" (which I suspect in Tomcat really just means it is recycled back into a pool) and the appender should still do its work.