Saturday, June 17, 2017

Logging with Mapped Diagnostic Context(MDC)

I was trying to write something on this topic from very long time since this is less known but very useful technology in case of high performance, multi threaded distributed systems.

What is MDC or NDC or ThreadContext(log4j 2)?

We all know that log4j is a widely accepted and most powerful logging mechanism in today's world. No application can be written without log4j. But its always messy since it works on the principle of log levels i.e. ALL< DEBUG < INFO < WARN < ERROR < FATAL < OFF. We will see how log level works in a different  post, Here

It generates so many messages in the log files depending on the log level that finding the real cause becomes very tedious.

MDC is a concept or feature of Log4j logging library which can be used to group related log messages together

Log4j also provides a similar utility called as NDC, known as Nested Diagnostic Context

Both of the above can be replaced with ThreadContext class in log4j 2.

The ThreadContext class provides a Map and a Set to replace MDC and NDC. The Thread Context Map allows any number of items to be added and be identified using key/value pairs, while ThreadContextStack allows one or more items to be pushed on the Stack and then be identified by their order in the Stack or by the data itself. 


Remember MDC is managed on a per thread basis and every child thread automatically inherits a copy of mapped diagonstice context from its parent. This is achieved by InheritableThreadLocal  i which is a sub class of  ThreadLocal class.

How to use MDC to log information in log4j

 You can put any information into Mapped Diagnostic Context or MDC by calling the put() method. MDC is a static class i.e. a class with just static methods, which means you can directly call them without creating any instance of MDC.

Remember, this information is stored as thread local variable, which may cause a memory leak in a web application if used incorrectly (
see). If you are using MDC to log client or order specific information e.g. orderId in a web application using a filter than you can also remove it once done.




try{
  MDC.put("tradeId", trade.getId());
}finally{
  MDC.remove.remove("tradeId");
}

By the way from log4j2 onwards, MDC and NDC (Nested Diagnostic Context) are merged into a class called ThreadContext So, instead of using MDC, you need to use ThreadContext class to put unique context data.

try{
   ThreadContext.put("tradeId", trade.getId());
}finally {
   ThreadContext.clear();
}


Once available in MDC, this information can be printed in the log file using PatternLayout. You can use %X{tradeId) to print tradeId in log messages, remember tradeId for different trades will be different, which allows you to trace logging messages for individual trades. 

This is same as we print the logs in log4j. We will see pattern layout in details here in details.


I will share a complete example in my coming blogs. Stay connected and happy reading :)


1 comment:

  1. GOOD post! Thanks for SHARING a good stuff related to DevOps, Explination is good, nice Article
    anyone want to learn advance devops tools or devops online training
    DevOps Training institute in Ameerpet
    DevOps Training in Ameerpet
    DevOps Training institute in Hyderabad
    DevOps Course in Hyderabad

    ReplyDelete

Java garbage collection

In this post , we ’ ll take a look at how garbage collection works , why it ’ s important in Java , and how it works in...