在Log4j里,是什么NDC和MDC之间的区别? 我能有一个简单的例子,在那里它们被使用?
Answer 1:
为扩大对链接这西科尔斯基放在评论:
NDC
在NDC的N代表嵌套的 ,这意味着你控制与堆栈单个值。 你“推”的字符串,那么你可以“推”另一每当处理使然; 当处理完成后即可弹出它关闭,看看前值。 这类上下文记录的将是一些根深蒂固的嵌套处理有用。
设置上下文字符串
NDC.push("processingLevel2");
log.info("success");
这将在你的日志,你必须一开始输出%x
(小写)模式:
log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %C %x = %m%n
MDC
该M代表映射 ,这给你一个不同类型的控件。 不要使用单个堆栈控制单个上下文字符串,可以使用名称/值对。 这是跟踪多个上下文位,如把用户名和IP到日志有用。
设置映射值:
MDC.put("userIP", req.getRemoteAddr());
MDC.put("userName", foo.getName());
log.info("success");
实施例MDC log4j的图案
大写的X与示例"userIP"
和"userName"
字符串。 这些都必须在你的代码,并在log4j的配置相匹配:
log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %X{userIP} %C %X{userName} = %m%n
我将这些组合成一个)上下文字符串*。
共同点和不同点
在这两种情况下,只要你做的log.info("success");
,输出将有您所提供的额外的上下文。 这是不是连接字符串一样更清洁log.info(req.getRemoteAddr()) + " success");
每次登录的时间。
请注意,有关于线程和资源两者之间的严重分歧。 特别是,NDC将保持把手给你的线程,如果你不勤奋弹出并清除NDC堆栈这会影响资源的释放。
从链接:NDC的使用会导致内存泄漏,如果你不定期调用NDC.remove()
方法。
Answer 2:
MDC允许您添加自定义标签的log4j。 例如:
%X{mytag} in log4j.xml
被引用
MDC.put("mytag","StackOverflow");
MDC子线程自动继承其父的映射诊断上下文的副本。
NDC操作,如push
, pop
, clear
, getDepth
和setMaxDepth
只影响当前线程的NDC。
文章来源: What is the difference between Log4j's NDC and MDC facilities?