使用MDC在log4j里记录用户信息

By
写代码

log是程序员的好朋友,合理的使用log系统,可以方便记录发生的bug、异常,尤其在debug无能的时候,log发挥至关重要的作用。Log4j是Apache的一个开源项目,是一个功能强大的日志组件。可以使用配置文件,即可在程序中使用它的日志输出机制。除此之外,作者(们)还写了SLF4j、logback等一系列的log组件,不过log4j应该是持续时间最久,用户基数也比较大的一支。

关于log4j的介绍,可以看 LOG4J官网。有使用方法等详细信息。但是有时候除了log,还希望输出一些附加信息,虽然可以在每个打印log的地方都插入这些信息,但显然是很不方便的,尤其对于一些固定来源的信息,不如给个上层调用来的方便。这就是此文要讨论的内容。

NDC vs MDC

NDC和MDC可以记录程序中上下文相关的信息,经常被用于输出log。NDC(Nested Diagnostic Context)即嵌套上下文诊断,MDC(Mapped Diagnostic Context)即映射的上下文诊断,二者的区别从表面上来看就是存储方式不一样。

更进一步的,NDC使用了栈的思想来存取信息,即把相关信息压入(push)/弹出(pop),这就是达到嵌套效果的原因:入A入B出B出A,或者,入A出A入B出B这样。在适当的时候push一堆进去,然后log4j在打印的时候就会从NDC里取值,这样,就很容易把当前NDC的内容给关联进去。通过这种机制,打log的时候就不用关注上下文或者NDC的信息,完全由系统去做。
NDC需要程序去控制合适push/pop适当的信息,并有可能操作不当(没有定期执行NDC.remove)造成内存泄漏。

MDC的机制和NDC类似,不过是采用了键值对应的思想来存取信息。

哪个更合适?

当需要打印的内容有嵌套关系的时候,用NDC;当键值就够用的时候,MDC。

将当前用户信息加入log

目前的Spring项目中某些操作希望简单输出具体用户信息到log里,所以就用了MDC处理这个。

目前使用了shiro来进行用户权限管理,SecurityUtils.getSubject().getPrincipal()是用来获取当前用户的。此处可以改成其他内容。

在spring的xml文件里声明一个bean,指向上面创建的类,方便注入。

在web.xml里声明一个filter,用它过滤所有request。

最后记得在logj.properties里加入user,格式为%X{user}(user为上面放到MDC里的key)

例如:

输出效果:

Comments: 5

  1. 什么话都不说,顶一个! :!:

    03月29日
  2. 标题那怎么显示空白啊。

    04月02日
  3. axiu同学的博文越来越不食人间烟火了,简直天书一样,怀念以前你写主题的日子啊

    04月06日
  4. :eek: :eek: 天书奇谈

    04月16日

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

:razz: