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. 🙂
- 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
- Reduced complexity with HTMX on the front end?
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.