The Source for Java Technology Collaboration
User: Password:



Rory Winston

Rory Winston's Blog

Why I love log4j

Posted by rwinston on October 03, 2004 at 03:25 PM | Comments (4)

I was wading through fixing a bug in an open-source package the other day, when I started thinking about the true value of consistent and detailed logging. Sounds like a no-brainer, I know. Well, check out the vast amount of open-source (and commercial, even if most of them won't admit it ;-)) code out there with little or no logging. Now, I'm frequently guily of this myself - it takes some discipline to stick with a consistent logging strategy, just as it does for a consistent test-driven strategy. But once it's done, it's done. The benefits are there for all for the duration of the life of the codebase, and it's much more difficult to retro-fit comprehensive logging on top of an existing codebase rather than develop with it from the outset (ditto for unit tests). Akin to this is the effort required to properly classify each message with the appropriate level, instead of blindly labelling every log statement as DEBUG or INFO. It's also easy to take for granted what a well-crafted logging framework can do - I never knew what say, a log4j Nested Diagnostic Context was before reading this entry in Gavin King's blog.

Which brings me neatly on to my next subject - good old log4j. It's easy to take it for granted, given what it does, it does so well, it tends to be ubiquitous, and logging's not really a very exciting subject, is it? (Not even when used in "Hello World" AOP examples ;-)). Nonetheless, I decided to take a look at what was going on with log4j development, and was mildly surprised to find it in a very healthy and active state. I hadn't realized that there was life after log4j 1.2.8, which has been out for a long time now, but the log4j committers have been very busy, and there are a whole host of new things coming in log4j 1.3, such as a new GUI (Chainsaw v2), enhancements to performance, configuration, i18n, and much more. There's also a little-publicized "Micro" version of log4j, called log4jMini, designed for J2ME-style applications.

It's the flexibility of log4j that I really like. Its functionality does make the java.util logging package look like the pale and watery imitation that it really is. We have a requirement on our current project to collect certain log categories and send them to a central syslog analyzer, in syslog format. With log4j, no problem - we can filter out the categories of interest and direct them to the syslog Appender, whilst sending them in parallel to the normal log files. A custom log level (e.g. "audit") and the JDBC Appender gives you a quick and easy auditing "framework".

And it's not just Java, either. A couple of months ago, I wrote my first piece of Perl code in about year. I was creating a Perl client for a secure Java-based SSO module. I decied to give the log4j-alike Log4Perl a try. This, as the name might suggest, is a pretty much a functionally equivalent implementation of trusty log4j. A typical Log4Perl configuration file might look something like this:

log4perl.rootLogger=DEBUG, A1
log4perl.appender.A1=Log::Log4perl::Appender::Screen
log4perl.appender.A1.layout=PatternLayout
log4perl.appender.A1.layout.ConversionPattern=%d %-5p %c - %m%n
log4perl.logger.com.foo=WARN

The interesting thing about log4perl is that if you pass it a log4j config file, it will attempt to internally convert it to a log4perl style config automatically. A typical log4Perl usage looks identical to the Java version:

my $logger = Log::Log4perl->get_logger("SSO");
$logger->debug("Using cipher: $cipher");

Nice and familiar.

I've also found the Log4E Eclipse plugin to be very handy. It removes some of the tedium re: inserting and initializing Loggers, and it can even automatically log entire classes and methods (although YMMV here - it can be a tiny bit flaky when automatically adding and removing method-level entry and exit points). It does also work with java.util.logging, if for some reason you want to work with that.

Anyone else found any useful log4j scenarios? Written any unusual Appenders, or found a use for some of the more advanced features (like NDCs)? Leave a comment if you have.


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • There are more appenders coming with log4j 1.3 as well as the opposite of appenders - receivers.

    Receivers accept events from an event source (an appender) and make the events available in the log4j framework. For example, there is a SocketReceiver that can process events generated by a SocketAppender.

    All existing appenders have matching receivers. There are also a number of receivers which can process events generated by other logging frameworks (including log4perl):

    - LogFilePatternReceiver (can parse -and tail- almost any simple log file format - including syslog)
    - 2 JDBC-based receivers - one that provides a schema
    - XMLSocketReceiver (can receive events from log4php, log4perl, log4cxx and the Java util.logging package)
    -UDPReceiver (can receive events from log4net)

    Chainsaw v2 supports receivers and is available now via Web Start at http://logging.apache.org/log4j/docs/chainsaw.html

    Feel free to email the log4j user list with questions.

    Scott

    Posted by: sdeboy on October 03, 2004 at 08:01 PM

  • Thanks for that Scott. Interestingly enough, there's an article at OnJava.com about log4j this week:

    http://www.onjava.com/pub/a/onjava/2004/09/29/smtp-logging.html

    Posted by: rwinston on October 05, 2004 at 12:15 PM

  • I am new to Log4J and would like to get a better understanding of the options for aggregating logs from multiple Log4j enabled applications into a centralized log collection. Any suggestions would be appreciated. Thanks...

    Posted by: jbarber on May 24, 2005 at 11:35 AM

  • Stupid Questions 16: What's the Difference Between Wildcard Generics and no Genericst

    Posted by: 3ufblogg on July 17, 2007 at 02:06 AM





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds