Leo*_*ord 33
扩展Sikorski在评论中提到的链接:
在NDC中,N代表嵌套,这意味着您使用Stack控制单个值.你"推"一个字符串,然后你可以在处理指令时"推"另一个字符串; 处理完成后,您可以将其弹出以查看以前的值.这种上下文日志记录在某些深层嵌套处理中很有用.
NDC.push("processingLevel2");
log.info("success");
Run Code Online (Sandbox Code Playgroud)
这将在您拥有%x(小写)模式的日志中输出:
log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %C %x = %m%n
Run Code Online (Sandbox Code Playgroud)
M代表映射,这为您提供了不同类型的控件.您可以使用名称/值对,而不是使用单个堆栈来控制单个上下文字符串.这对于跟踪多个上下文位非常有用,例如将用户名和IP放入日志中.
MDC.put("userIP", req.getRemoteAddr());
MDC.put("userName", foo.getName());
log.info("success");
Run Code Online (Sandbox Code Playgroud)
带有示例"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
Run Code Online (Sandbox Code Playgroud)
我将这些组合成一个上下文字符串*.
在这两种情况下,无论何时执行此操作log.info("success");,输出都将具有您提供的其他上下文.这比log.info(req.getRemoteAddr()) + " success");每次登录时连接字符串要清晰得多.
请注意,两者在线程和资源方面存在严重差异.特别是,如果您不擅长弹出和清除NDC堆栈,NDC将保留您的线程的句柄,这可能会影响资源的释放.
从链接:如果您不定期调用该NDC.remove()方法,NDC使用可能会导致内存泄漏.
MDC允许您为log4j添加自定义标记.例如:
%X{mytag} in log4j.xml
Run Code Online (Sandbox Code Playgroud)
被引用
MDC.put("mytag","StackOverflow");
Run Code Online (Sandbox Code Playgroud)
MDC子线程自动继承其父级的映射诊断上下文的副本.
NDC操作,例如push,pop,clear,getDepth和setMaxDepth只影响当前线程的NDC.