What is the difference between Log4j's NDC and

2019-01-13 18:31发布

In Log4j, what is the difference between NDC and MDC? Can I have a simple example where they are used?

标签: logging log4j
2条回答
看我几分像从前
2楼-- · 2019-01-13 19:08

To expand on the link which Sikorski put in the comments:

NDC

In NDC, the N stands for nested, meaning you control a single value with a Stack. You "push" a string, then you can "push" another whenever processing dictates; and when processing is complete you can pop it off to see the former value. This sort of contextual logging would be useful in some deeply-nested processing.

Setting the context string

NDC.push("processingLevel2"); 
log.info("success");

This will get output in your log where you have the %x (lowercase) pattern:

log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %C %x = %m%n

MDC

The M stands for mapped, and this gives you a different type of control. Instead of using a single stack to control a single contextual string, you use name/value pairs. This is useful for tracking multiple contextual bits, such as putting username and IP into the log.

Setting the mapped values:

MDC.put("userIP", req.getRemoteAddr());
MDC.put("userName", foo.getName());
log.info("success");

Example MDC log4j pattern

Uppercase X with the example "userIP" and "userName" strings. These must match in your code and in the log4j config:

log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %X{userIP}  %C %X{userName} = %m%n

I would combine these into one )context string*.

Similarities and Differences

In both cases, whenever you do the log.info("success");, the output will have the additional context you have provided. This is much cleaner than concatenating strings like log.info(req.getRemoteAddr()) + " success"); every time you log.

Note that there are serious differences between the two with respect to threading and resources. In particular, NDC will keep handles to your threads which can affect the freeing of resources if you are not diligent about popping and clearing the NDC stack.

From the link: NDC use can lead to memory leaks if you do not periodically call the NDC.remove() method.

查看更多
别忘想泡老子
3楼-- · 2019-01-13 19:12

MDC allows you to add custom tags for log4j. eg:

%X{mytag} in log4j.xml

is referenced by

MDC.put("mytag","StackOverflow");

MDC child thread automatically inherits a copy of the mapped diagnostic context of its parent.

NDC operations such as push, pop, clear, getDepth and setMaxDepth affect the NDC of the current thread only.

查看更多
登录 后发表回答