Analyzing Resin Logs with Apache Chainsaw
Apache Chainsaw is a popular graphical logging tool for Java. Even though it’s based on Log4j and Resin’s logging uses java.util.logging, you can use Chainsaw to analyze Resin’s logs in real time. In this blog, I’ll show you how to connect Resin with Chainsaw using a technique that can be extended to other Log4j-based analysis tools.
The basic idea of hooking up Resin with Chainsaw is to have Resin send its log events over a socket to a Chainsaw Receiver. In java.util.logging we can achieve this effect by creating a SocketHandler with an XMLFormatter. On the Chainsaw side, we create a receiver that listens to a port and understands java.util.logging’s XML format.
Register the Log Handler
First we need a small piece of Java to register a SocketHandler, formatted with an XMLFormatter. This handler will connect to Chainsaw and send log events. Here’s a simple example:
import javax.annotation.PostConstruct;
import java.io.*;
import java.util.logging.*;
public class ChainsawHandler {
private String _host = "localhost";
private int _port = 4448;
private String _name;
public void setHost(String host)
{
_host = host;
}
public void setPort(int port)
{
_port = port;
}
public void setName(String name)
{
_name = name;
}
@PostConstruct
public void init()
throws IOException
{
Logger logger = Logger.getLogger(_name);
SocketHandler handler = new SocketHandler(_host, _port);
handler.setFormatter(new XMLFormatter());
logger.addHandler(handler);
System.err.println("added " + handler + " to " + logger);
}
}
Compile this class, create a jar, and copy the jar to ${resin.root}/ext-lib. Now to get this code to run on startup, just add the following to your resin.xml configuration:
<cluster id="app-tier">
<example:ChainsawHandler xmlns:example="urn:java:com.caucho.example">
<ejb:Startup xmlns:ejb="urn:java:javax.ejb"/>
<example:name>com.caucho</example:name>
<example:host>localhost</example:host>
<example:port>4448</example:port>
</example:ChainsawHandler>
Adjust the host, port, and logger name as you like.
Configure Chainsaw
To configure Chainsaw to accept the log events from Resin, we’ll need to add a new Receiver:
- Start Chainsaw
- Select “Let me define Receivers manually”
- Just right click on the Receivers menu on the right
- Select “New XMLSocketReceiver…”
- In the XMLSocketReceiver dialog box, change the value of the “decoder” property to “org.apache.log4j.xml.UtilLoggingXMLDecoder”
- Set the name to “ResinReceiver”
- Adjust the port to match the one you set above in the Resin configuration (default is 4448)
- Click Ok
- Start Resin… you should see Resin’s startup logs in Chainsaw!

Conclusion
This approach can be used to direct Resin log output to any other Log4j-based tools. The code given is just a starting point - it doesn’t look like the SocketHandler tries to reconnect or add reliability, so you may need to do some tweaking depending on your environment. Another option is to add a Quercus/PHP page that adds a SocketHandler at runtime. Please let us know if you use other log analysis tools and if this option works for them as well.

December 20th, 2009 at 11:59 pm
Assuming you have a regular text file output by default, you can use LogFilePatternReceiver to parse & tail the log in real-time in Chainsaw. If you need Jakarta Commons-VFS supported file systems, you can use VFSLogFilePatternReceiver also.
There is a configuration example available from the Welcome tab inside Chainsaw.
December 21st, 2009 at 2:48 pm
sdeboy,
Cool. Thanks for the tip!
Emil
February 2nd, 2010 at 7:56 am
Emil,
The code example for this is not showing up (there is a GeSHi error saying it can’t find it). For anyone looking for the code, we did seem to find it here: http://www.facebook.com/note.php?note_id=218721509812 though it would be good to get this blog entry fixed.
Allen
February 2nd, 2010 at 9:36 am
Hi,
Can this be used with Resin 3.1.6? It seems as though the XML config is not supported - is there another way to configure this for Resin 3.1.6.
Thanks,
Allen
February 4th, 2010 at 3:56 pm
Hi Allen,
Thanks for the note on the code. Should be fixed now.
You can do the same thing in 3.1.6, just use the <bean> syntax instead:
<bean name="chainsaw-handler"> <type>com.caucho.example.ChainsawHandler</type> <init> <name>com.caucho</name> <host>localhost</host> <port>4448</port> </init> </bean>http://www.caucho.com/resin-3.1/doc/env-tags.xtp#bean
Emil