MDC
简介
MDC(Mapped Diagnostic Context) 是 Log4j 日志库的一个概念或功能,可用于将相关日志消息分组在一起。
使用方式
首先需要编写一个过滤器用于拦截请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import jakarta.servlet.*; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC;
import java.io.IOException; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.UUID;
@Slf4j public class MdcFilter implements Filter {
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { HttpServletRequest httpServletRequest = (HttpServletRequest) request; String traceId = httpServletRequest.getHeader("traceId"); if (traceId == null) { traceId = UUID.randomUUID().toString(); } MDC.put("traceId", traceId); MDC.put("ts", String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli())); log.info(httpServletRequest.getRequestURL() + " call received"); chain.doFilter(request, response); } finally { MDC.clear(); } } }
|
然后需要将此过滤器加载到 Spring :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean;
@SpringBootApplication public class Application {
@Bean public FilterRegistrationBean<MdcFilter> loggingFilter() { FilterRegistrationBean<MdcFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new MdcFilter()); registrationBean.addUrlPatterns("/*"); return registrationBean; }
public static void main(String[] args) { SpringApplication.run(Application.class, args); }
}
|
编写如下配置文件设置显示样式:
1 2 3 4 5 6 7 8
| server: port: 8080 spring: application: name: demo Logging: pattern: level: '%5p [${spring.application.name:},%mdc{traceId:-},%mdc{ts:-}]'
|
然后需要编写一个样例的 Controller
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import lombok.extern.slf4j.Slf4j; import org.slf4j.MDC; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
@Slf4j @RestController @RequestMapping public class DemoController {
@GetMapping("/demo") public String hello() { log.info("TraceId: {} - Hello World!", MDC.get("traceId")); return "Hello World!"; }
}
|
访问 http://localhost:8080/demo 即可看到结果日志。
参考资料
How to distinguish logging per Client or Request in Java? Use MDC or Mapped Diagnostic Context in Log4j Example
基于MDC实现长链路跟踪