PreviousNext…

Logging in Java, when you’re not on Domino

In addition to his Adobe Flex stuff, m’fellow London Developer Co-op bod Mark has been doing some posts on Java-based alternatives to familiar Domino concepts: configuration documents and scheduled agents so far. The lovely chap then forced me in on the act, and in fairness it has been rather a while since I posted anything remotely useful or technical.

So here goes, a lightweight guide to logging in Java, seeing how logs are close to my heart. Of course, as with anything in Java, there is no One True Way, but this is as good as any (feel free to shoot me down in flames).

If you’re well-behaved when it comes to your Notes / Domino development, you use some kind of logging, even if it’s only during the debug phase of your development project. Domino provides a capable framework for this—NotesLog—and Julian Robichaux has gone one (thousand) better with his excellent OpenLog project.

Your Java code should be no different. OpenLog works for Java as well as Lotusscript, so you’d do well to use it in your Domino Java agents. If you’re coding non-Domino stuff though, you might want to consider one of the Java logging frameworks. There are a fair few, and it gets confusing when you see mention of log4j piled on top of talk about org.apache.commons.logging and the like.

In Java you have to justify everything

Being a lazy sod, I can’t be doing with all the advanced guff about appenders, custom configurations, different libraries, ya-da ya-da. I just want to be able to log some stuff somewhere consistently, and move on to the next problem. I tend to choose something that looks OK, and run with it. My current project has a fair few developers dipping in and out of it, with a number of possible forks possible downstream. To this end, I opted for the Apache commons-logging project as tiny layer above the venerable log4j framework. Here’s what the commons-logging wiki has to say on the matter:

If however, like the Jakarta Commons project, you’re building a tiny little component that you intend for other developers to embed in their applications and frameworks, and you believe that logging information might be useful to those clients, and you can’t be sure what logging framework they’re going to want to use, then commons-logging might be useful to you.

Fair enough. Let’s go!

  1. Add the commons-logging JAR to your project dependencies
  2. Ensure relevant classes import the relevant packages (org.apache.commons.logging.Log and org.apache.commons.logging.LogFactory)
  3. Initialise your log*:
    private static Log log = LogFactory.getLog(YOURCLASSNAME.class);
    
  4. Use the shiny new log in your code:
    log.debug("WidgetOne fully instantiated; now populating WidgeTwo");

Simple! We’re using log4j as our implementation, which is arguably the most common logging package. If you want to pick up an example log4j.xml configuration, then this should do the trick (link to an annotated, teeny tiny XML file).

Silly footnotes

* - You can be a little fancier here if you must, using reflection to grab the name of the current class, thus rendering your single line of code truly portable **.

** - Oh all right:

String cn = this.getClass().getName();
System.out.println(cn.substring(cn.lastIndexOf(".") + 1));

getClass().getSimpleName();

Filtering

Logging is so prevalent in the Java world, that you may find that your appender of choice gets rather cluttered (tsk). If you wish for more purity in your console / log file / mail / whatever, then you can add <logger> entries in your log4j configuration to filter out the guff. For example, in our project we don’t care about messages from the Hibernate package, so this is what we do in our log4j.xml file:

<logger name="org.hibernate" additivity="false">
  <!-- ignore all but most serious messages from Hibernate -->
  <level value="error" />
  <appender-ref ref="stdout" />
</logger>

… This way Hibernate quietly sits in the corner unless it hits a major error. You can add more logger nodes for various packages, even down to the full class level. Alternatively, you can ignore excluding stuff, and simply do a filter which includes just your package (in this example, com.benpoole.winkle):

<logger name="com.benpoole.winkle">
  <!-- Print only messages of level DEBUG (or higher) for winkle -->
  <level value="warn"/> </logger>

Further reading

There’s a reasonable wiki page out there, all about setting up your log4j file. It also provides guidance as to how to convert an older-style log4j.properties file into its XML equivalent: Log4j XML Configuration Primer. The wiki goes on to detail the various Appenders you can use (e.g. file, console, SMTP…) and even sort of tells you about “additivity”.

In short, it tells you more than I. Enjoy, and log on!

Comments on this post are now closed.

About

I’m a software architect / developer / general IT wrangler specialising in web, mobile web and middleware using things like node.js, Java, C#, PHP, HTML5 and more.

Best described as a simpleton, but kindly. You can read more here.

";