在典型的 servlet 环境中,每个请求都有自己的线程。添加日志记录 MDC 来为请求生成唯一的请求 ID 可以通过简单的 servlet 过滤器来实现。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
String requestId = UUID.randomUUID().toString();
HttpServletResponse httpServletResponse = (HttpServletResponse)response;
httpServletResponse.setHeader("requestId", requestId);
MDC.put("requestId", requestId);
chain.doFilter(request, response);
} finally {
MDC.remove("requestId");
}
}
Run Code Online (Sandbox Code Playgroud)
日志记录配置。
<Pattern>%d %-5level %X{requestId} [%t] %C{10}:%L %m%n</Pattern>
Run Code Online (Sandbox Code Playgroud)
样本记录。
2024-02-04 10:29:55,160 INFO 99cd4d64-5d7c-4577-a5d3-cb8d48d1dfd5 [http-nio-8080-exec-6] c.s.q.UserController:65 Deleteing user 'test'
2024-02-04 10:29:55,260 INFO 99cd4d64-5d7c-4577-a5d3-cb8d48d1dfd5 [http-nio-8080-exec-6] c.s.q.UserController:70 Successfully deleted user 'test'
Run Code Online (Sandbox Code Playgroud)
对于 Java 21+ 中的虚拟线程,我的印象是线程可以在等待任何 IO 时自动挂起请求,并且线程可以开始处理其他请求。在这种情况下,当线程开始服务其他请求时,日志记录 MDC 似乎可以“渗入”其他请求日志。如何解决这个问题,以便我可以继续将唯一值添加到每个请求的日志记录语句中?