How to use AsyncAppender in log4j?

47,208

Solution 1

Answering my own question.

In the log4j config file(usually it's log4j.xml or log4j.properties) we should define AsyncAppender which would refer to a real appender(it may be our own defined class like in my case).

So I wrote a WebServiceAppender class which extends AppenderSkeleton and implements 3 abstract methods. The main method is "append" which connects to the web service and sends all the information to it. That's it.

Solution 2

Add AsyncAppender in log4j config file which will refer to a real appender. For demo: adding asyncappender to console appender in log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="[%p] %d{dd MMM hh:mm:ss aa} %t [%l] %m%n"/>
    </layout>
</appender>
<appender name="async" class="org.apache.log4j.AsyncAppender">
    <param name="BufferSize" value="500"/>
    <appender-ref ref="console"/>
</appender>
<root>
    <priority value="all"></priority>
    <appender-ref ref="async"/>
</root>
</log4j:configuration>

Solution 3

We wanted to use log4j.AsyncAppender but couldn't find any setter methods to attach other appenders at the log4j.property file. So we extended the log4j.AsyncAppender class and added a setter to add other appenders. This has helped the main program thread to be independent of log4j's logging operation. The details below.

log4j entry:

Define a logger 'com.noPath' with log4j File Appender, 'fileAppender'. Note that the logger path is immaterial and hence the name 'com.noPath'

log4j.logger.com.noPath=DEBUG,fileAppender
log4j.appender.fileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.fileAppender.File=c:/test.log

Define the logger that business needs, 'com.business', Attach the File appender of previous step, 'fileAppender', to the log4j AsyncAppender through a custom class com.log.AsyncAppenderHelper which extends log4j AsyncAppender

log4j.logger.com.business=DEBUG,asyncLog
log4j.appender.asyncLog=com.log.AsyncAppenderHelper
log4j.appender.asyncLog.appenderFromLogger=com.noPath

The java class com.log.AsyncAppenderHelper extending log4j.AsyncAppender, have it available in the class path.

package com.log
import java.util.Enumeration;
import org.apache.log4j.Appender;
import org.apache.log4j.AsyncAppender;
import org.apache.log4j.Logger;

/*
 * This class helps configure to AsyncAppender from log4j as part of log4j.properties
 * You can inject other appenders to AsyncAppender using the AsyncAppenderHelper
 * This would free up the main program thread to be independent of log4j's logging operation
 * @Author http://www.linkedin.com/in/jobypgeorge
 */

public class AsyncAppenderHelper extends AsyncAppender{

    public AsyncAppenderHelper(){
        super();
    }

    public void setAppenderFromLogger(String name){
        Logger l = Logger.getLogger(name);

        Enumeration<Appender> e = l.getAllAppenders();

        while(e.hasMoreElements()){
             Appender a = e.nextElement();
             this.addAppender(a);
             System.out.println("The newAppender "+a.getName() +" attach status "+this.isAttached(a));
        }

     }
}
Share:
47,208
Sergey
Author by

Sergey

I'm a student.

Updated on April 01, 2020

Comments

  • Sergey
    Sergey about 4 years

    How to use AsyncAppender in log4j in order to write log message to the web service? Should I create my own Appender which would extend AsyncAppender or just attach custom appenders to the AsyncAppender? If the second choice is correct, where should I take the AsyncAppender object? Is there any example?