Adding traceId to logs to track links is very common in distributed systems. We implemented it based on org.slf4j.MDC, using ThreadLocal as the principle.

Add TRACE_ID to the request, or assign a value directly to the request header. Using interceptors, interceptions handle:

public class TestTraceInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object Handler) throws Exception {// Internal MDC MDC. Put (Constants.TRACE_ID, traceId()); return super.preHandle(request, response, handler); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { super.afterCompletion(request, response, handler, ex); MDC.clear(); } public static String traceId() { return UUID.randomUUID().toString().toUpperCase(); }}Copy the code

Add traceId to the return log: use in conjunction with ResponseBodyAdvice to enhance the return parameter by encapsulating additional parameters

@ControllerAdvice public class ResponseVOFilterAdvice implements ResponseBodyAdvice<Object> { private static final Logger logger = LoggerFactory.getLogger(ResponseVOFilterAdvice.class); @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<? >> converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<? >> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if (body instanceof BaseDataVO) { BaseDataVO dataVO = (BaseDataVO) body; dataVO.setTraceId(MDC.get(Constants.TRACE_ID)); logger.info("ResBody:{}", JacksonUtils.toJson(dataVO)); } return body; }Copy the code

Log printing Supplementary traceId printing:

<SensitivePatternLayout pattern="%d{yyyy/MM/dd HH:mm:ss.SSS} %X{TRACE-ID} %t [%p] %c{1} (%F:%L) %msg%n">
Copy the code

Asynchronous thread tracecId log printing:

public class MdcTaskDecorator implements TaskDecorator { @Override public Runnable decorate(Runnable runnable) { Map<String, String> contextMap = MDC.getCopyOfContextMap(); return () -> { try { MDC.setContextMap(contextMap); runnable.run(); } finally { MDC.clear(); }}; }}Copy the code

Add decorator to create thread pool:

executor.setTaskDecorator(new MdcTaskDecorator());
Copy the code

Effect: 2020/07/08 18:56:00.278 2e1d7f0b-c9A4-482A-9C72 -2B393676A54B Thread-94 [INFO] XXXXXXX