Log4j2之ThreadContext

2023-10-12 23:57:01 浏览数 (2)

Log4j2之ThreadContext

简介

系统中使用log4j2作为日志系统,然而在高并发的情况下,多次请求的日志参杂在一起,要跟踪某个用户一次的请求操作所有日志是很麻烦的。幸运的是log4j中有相应的解决方案。

NDC和MDC

NDC(Nested Diagnostic Context)和MDC(Mapped Diagnostic Context)是log4j种非常有用的两个类,它们用于存储应用程序的上下文信息(context infomation),从而便于在log中使用这些上下文信息。NDC采用了一个类似栈的机制来push和pop上下文信息,每一个线程都独立地储存上下文信息。比如说一个servlet就可以针对每一个request创建对应的NDC,储存客户端地址等等信息。MDC和NDC非常相似,所不同的是MDC内部使用了类似map的机制来存储信息,上下文信息也是每个线程独立地储存,所不同的是信息都是以它们的key值存储在”map”中。

NDC和MDC的原理是用了java的ThreadLocal类。可以针对不同线程存储信息。但是今天在log4j2上使用时发现没有找到NDC和MDC。查找官方文档,原来是换成了ThreadContext。操作也挺简单:

X占位符

在官方文档的Pattern Layout章节的Patterns子章节下,可以看到对于%X占位符的描述。

描述中提到,存入ThreadContext的映射关系,能够输出到对应的X占位符中,这正好是显示登录者信息的理想实现方式。

官方文档地址:Log4j 2 API Thread Context

Demo实现

  1. 修改log4j2配置文件的PatternLayout.pattern格式,追加[%X{userName}]占位符
代码语言:javascript复制
<PatternLayout pattern="%d %-5p [%t][%X{userName}] %C{2} (%F:%L) - %m%n"/>

2.追加Java代码,登录时,往ThreadContext存入映射关系,这里为了方便演示,存了固定值

代码语言:javascript复制
 ThreadContext.put("userName","kevin");

3.追加Java代码,在退出登录后,清除ThreadContext的映射关系

代码语言:javascript复制
ThreadContext.clear();

至此,实现完毕。

效果

代码语言:javascript复制
2023-10-12 10:01:37,932 INFO  [http-nio-8082-exec-4][kevin] aspect.LogAspect (WareLogAspect.java:56) 

0 人点赞