是什么Log4j的NDC和MDC设施之间的区别?(What is the difference be

2019-07-17 19:14发布

在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操作,如pushpopcleargetDepthsetMaxDepth只影响当前线程的NDC。



文章来源: What is the difference between Log4j's NDC and MDC facilities?
标签: logging log4j