在Log4j中,NDC和MDC有什么不同?我可以有一个使用它们的简单示例吗?
发布于 2013-03-01 01:43:32
对西科尔斯基在评论中提出的link进行扩展:
NDC
在NDC中,N代表嵌套,这意味着您可以使用Stack控制单个值。您“推”了一个字符串,然后只要处理指示,您就可以“推”另一个字符串;当处理完成时,您可以将其弹出以查看前一个值。这种上下文日志记录在一些深度嵌套的处理中会很有用。
设置上下文字符串
NDC.push("processingLevel2");
log.info("success");这将在具有%x (小写)模式的日志中获得输出:
log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %C %x = %m%nMDC
M代表映射,这为您提供了一种不同类型的控制。您可以使用名称/值对,而不是使用单个堆栈来控制单个上下文字符串。这对于跟踪多个上下文位很有用,例如将用户名和IP放入日志中。
设置映射值:
MDC.put("userIP", req.getRemoteAddr());
MDC.put("userName", foo.getName());
log.info("success");MDC log4j模式示例
包含示例"userIP"和"userName"字符串的大写X。在您的代码和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.remove()方法,NDC的使用可能会导致内存泄漏。
发布于 2013-01-03 16:02:20
MDC允许您为log4j添加自定义标记。例如:
%X{mytag} in log4j.xml被引用
MDC.put("mytag","StackOverflow");MDC子线程自动继承其父线程的映射诊断上下文的副本。
push、pop、clear、getDepth、setMaxDepth等NDC操作只影响当前线程的NDC。
https://stackoverflow.com/questions/14134734
复制相似问题