This is an old article. You might want to check out a newer one I wrote for Logback using the same concepts.
Check out my latest stuff to the right below. 🙂
- HTMX + SSE: Easy updates of HTML state with no JavaScript
- Loading environment variables in code: the simple way
- Replacing legacy systems: Proxy to learn and control
- Full stack development with KTor and HTMX ❤️
- Logback superpowers for better observability
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(“uname”, 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 our 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.
7 replies on “Log4J and the Mapped Diagnostic Context”
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
Ah, excellent! 🙂 I’ll have a look at it as soon as possible.
Great Resource. I have been looking for great information to extend my knowledge of Log4net to use in my current project.
thank you very much, very useful
really helpfull
[…] Log4j and the Mapped Diagnostic Context […]
Dope thanks.