Log4J and the Mapped Diagnostic Context

Logging has been one of those things we havn’t tended to properly with our current project. I don’t use it much during development as I’m a debugger fan, but it will be increasingly important as we hit production, and need to diagnose errors after they occur. So I had to sit down and figure out some aspects of our logging.

One of the special things with web applications is that one log serves several clients and/or users. This means that a long log of events might be hard to decipher when you have concurrent sessions going on. It would quite frankly become one hughe mess, and impossible to follow a trail to find steps that lead to the error. The solution: the Mapped Diagnostic Context.

The Mapped Diagnostic Context allows you to put something in as a key in a map. Let’s say that you want to store the username under a “uname” key, you would do: MDC.put(“uanme”, user.getUsername()) . Alright, seems simple enough, but what use is it? The clue is that the MDC is a ThreadLocal, which means that whatever you put in the MDC will be valid for the current Thread execution, and no more. So when I use a ServletFilter to set the username at the beginning of the thread, all log statements that contains %X{uname} will also print the username. This works through all layers of our application, even though many of them are not aware of the logged in user, or username. This is possible because a ThreadLocal can contain information available throughout a complete thread, without needing to pass it in through method signatures.

We have even added a little extra (the five last characters of the session id) to distinguish the different sessions a user might have and stored it in the MDC so all out log statements can be tied to a user and a session.

For more details on ThreadLocal see this article. Based on Build Flexible Logs With log4j.

4 thoughts on “Log4J and the Mapped Diagnostic Context

  1. Scott

    You can take advantage of MDC, even in your log files, using the latest version of log4j’s Chainsaw (Chainsaw’s available via Web Start at http://logging.apache.org/log4j/docs/chainsaw.html)

    Chainsaw displays each MDC key as a unique column in the UI, and you can use the expression syntax to search/colorize or filter based on the entry. For example, to display only events for uname=’joe’, specify this expression in the ‘refine focus’ field:
    PROP.uname == ‘joe’

    Chainsaw supports a number of event sources via receivers – including the LogFilePatternReceiver that can parse and tail arbitrary log files, SocketReceiver, two database-based receivers and receivers that can process events generated by log4perl, log4net, log4cxx, log4php and jdk1.4 util.logging.

    There’s a tutorial available from the Welcome tab explaining some of how Chainsaw works.

    Feel free to email if you have questions,
    Scott

    Reply

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>