NOTE: This article is 3 years or older so its information may no longer be relevant. Read on at your own discretion! Comments for this article have automatically been locked, refer to the FAQ
for more details.
I've been updating logging in the web services I look after so that the WS-A MessageID
can be logged for each request and for all of the messages written to the log during that request. On the most part putting this value it into the MDC
and configuring the appender to write it out to the log is all that's required. However, when you start using thread pools e.g. with ThreadPoolExecutor
the MDC goes haywire and that's because and I quote..."The MDC is managed on a per thread basis."
When using a thread pool the processing starts to happen outside of the main web service thread so the MDC
that is being used is completely unrelated to the original request. This means you can start logging data for requests that have completed running already.
This is how I went about making sure the correct MDC
I created a small wrapper class that implements Callable
. Since the Callable
is going to be created within the context of the original web service thread the MDC
that is available there is the correct one. So in the constructor I create a clone of that MDC
I also implement the call()
method - this is called in the context of whatever Thread
happens to be available from the pool so the MDC
is cleared first to remove any previous requests' data, then I copy values from the cloned MDC
context into the current MDC
and call the abstract process()
To use this all I have to do is extend MdcCallable
and implement the process()
method instead of the usual approach of implementing Callable
and the call()
It may not be very performant making clones of the MDC
context every time so we ended up optimising this to look for specific key/values from the MDC
but the approach is much the same as described above.
For this to work you will need the 1.2.17
version of log4j
Hope you found this post useful...
...so please read on! I love writing articles that provide beneficial information,
tips and examples to my readers. All information on my blog is provided free of
charge and I encourage you to share it as you wish. There is a small favour I ask in return however -
engage in comments below, provide feedback, and if you see mistakes let me know.
If you want to show additional support and help me pay for web hosting and
domain name registration,
donations, no matter how small, are always welcome!
Use of any information contained in this blog post/article is subject to this disclaimer
Other posts you may like...