Originally uploaded by Batram

Have your application ever been blocked by Log4j logging? Ideally your application should be less dependable on external logging services, SMTPAppender or JMSAppender, etc, but you need one to monitor important events remotely.

The AsyncAppender lets you log events asynchronously. It will collect the events sent to it and then dispatch them to all the appenders that are attached to it. You can attach multiple appenders to an AsyncAppender, but I won’t do that. The AsyncAppender uses a separate thread to serve the events in its buffer. The default buffer size is 128 and the blocking is set to true, which means that the logging is blocked when the buffer is full. I don’t know why the default blocking is set to true. Reading the source codes, if it’s set to false, the logging won’t be blocked since events are summarized and discarded. I’ve got to test it.

I have used JRuby to test the AsyncAppender and found it very handy again.

First of all, I needed an Log4j Appender that runs a bit slow. So, I have created a very simple SlowAppender.rb, which is a subclass of Log4j AppenderSkeleton. You just need to implement the append method.

SlowAppender < org.apache.log4j.AppenderSkeleton
def append(event)
sleep 1
puts layout.format(event)

Since I can’t configure it in log4j.xml, I add it to an AsyncAppender programmatically in a test JRuby script.

logger = Logger.getRootLogger()
slow = SlowAppender.new
slow.setLayout(PatternLayout.new("%d{ABSOLUTE} %-5p [%c{1}] %m%n"))
async = logger.getAppender("ASYNC")

Full source codes and the result of the test script are available here.

You may not like that some events are discarded, but ideally you should be notified by catastrophic problems with remote logging services before that. What’s important to you is that your application keeps working without being disrupted by other services.

You should also consider using StringMatchFilter to avoid sending unnecessary log messages to remote logging services. A flood of unnecessary logging messages will cause problems to remove logging services that are most likely shared with other applications.

A while back I came across RSSAppender and I think it’s a very simple way to retrieve and aggregate important logging events. How it works? Why don’t you test it in JRuby?