Log4j MDC

Log4j MDC

问题

在项目中需要分类收集处理日志信息,使用log4j的MDC线程中添加分类信息。不过最近却出现信息记录错误的情况,具体来说就是会出现本来属于下一个分类的一部分信息莫名的记录到上一个分类的日志文件中了。

问题原因分析

MDC 需要在完成后被重置,或者说清空。因为MDC是绑定线程的,所以,在大多数简单的使用的情况下,例如在服务器端接受请求的入口处,设置一个MDC信息,如果服务器这个程序任务的程序结束后会被丢弃,那么也不会出现什么问题,但是如果是一个线程池,池的线程会被重复利用的情况下,如果你没有结束后清楚MDC的信息,那么在下次设置之前,上次设置以后的这段日志,就会出现数据错乱的情况。

解决方法

在log4j 1.2.16以后的版本,MDC直接提供了clear() 方法即:

1
MDC.clear()

或者手动清理MDC

1
2
MDC.getContext().clear();
// 需要校验一下MDC.getContext() 不为null

tip

当我们在项目中使用 ThreadLocal 时,在一个线程结束时也需要清空 ThreadLocal中的数据,否则也可能会出现上述情况。