I’ve had to configure Log4J several times over the years and I’ve never particularly enjoyed the experience. Log4J is in general just not well documented, surprisingly so since it is used extensively in the Java world.
So I found myself going through some examples in the first part of Spring in Action and needing to configure Log4J. So off to the Log4J site only to run into familiar problems:
- Most of the documentation forgets to mention the easiest way to configure Log4J so that you don’t have to explicitly load a file is to add log4j.xml to the CLASSPATH.
- Almost all the documentation and tutorials show log4j.properties instead of log4j.xml
- The documentation and tutorials don’t explain most of the options for the XML tags.
- There just isn’t a good solid recent tutorial. (Or at least I haven’t run across it)
So I’m documenting my Log4J setup, mainly so I don’t have to research it again sometime down the road. The two best tutorials I could find were ‘Don’t Use System.out.println()! and Log4J Tutorial by Ashley J.S Mills. The first details most of the options for layout parameters and focuses on the log4j.properties format. The XML configuration is better covered Ashley J.S. Mills article.
Following below is my sample log4j.xml file:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.SimpleLayout"/> </appender> <category name="com.springinaction.chapter01"> <priority value="debug"/> </category><root><priority value="info"/> <appender-ref ref="ConsoleAppender"/> </root> </log4j:configuration>
The appender section simply defines a Console Appender and a simple layout. The category section defines a package and a priority level. It’s important that you put this before the root section apparently in the file or you get errors. If you want to log all the debug statements just from your stuff you leave this set to debug. This overrides the root section. The root section is ‘required’ or again you get errors about Log4J configuration. In this case its set to ‘info’ for the priority so I don’t get a bunch of debugging messages I don’t care about in the Spring framework.
Finally you can then use Log4J in any class by adding the following instance variable:
Logger log = Logger.getLogger(Sample.class);
Then when you want to dump something to the logger a simple call:
log.debug("Entering printThis() Method");
This simple example doesn’t show File Appenders or nicely formatted statements with date and time stamps, but it does show the bare minimums to get up and running, so hopefully I’ll never have to research it again.
My actual opinion of loggers is that they often are signs of bigger problems such as insufficient unit tests. Loggers can be overused as a basic debugging strategy. I prefer to go back and write more unit tests rather than rely on logging to debug a problem. They also tend to clutter up code, though that will theoretically become less of a problem with AOP strategies. Still they’re generally handy especially for debugging production issues.