In order to facilitate project log query, you can add a custom identifier to the log configuration file and add a uuid to the log header to achieve the purpose of adding a unique identifier for the same interface request identifier.
Here’s a simple way:
1. By looking at the slf4j source code comments, the MDC class in the org.slf4j package provides MDC (Mapped Diagnostic Contexts) for log4j and logback, which is a thread-safe container for storing diagnostic logs. )] function, the static method put(String key, String val) in the MDC class can put the custom identification key into the MDCAdapter. Finally, through the reflection mechanism, the key corresponds to the identification key in the xml configuration, and the value of the key identification is added. Enter the log content.
2. Add a custom logo to the logback-spring.xml configuration file. Add [%X{trace_uuid}] to the configuration.
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <!-- Console output log --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>[%X{trace_uuid}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%c] %L - %msg%n</pattern> </encoder> </appender> <!--Generate a log file every day and save the log file for 30 days. --> <appender name="DayFile" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>logs/log.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>logs/log.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>[%X{trace_uuid}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%c] %L - %msg%n</pattern> </encoder> </appender> <!--Specify the logger name as the package name or full class name and specify whether the level additivity setting is passed to the root logger --> <logger name="slf4j" level="INFO" additivity="false"> <appender-ref ref="STDOUT"/> <appender-ref ref="DayFile"/> </logger> <!--The classes under the slf4j2 package are passed to the root logger at the ERROR level--> <logger name="slf4j2" level="ERROR"/> <!--Root logger control--> <root level="INFO"> <appender-ref ref="STDOUT"/> <appender-ref ref="DayFile"/> </root> </configuration>
Depending on the actual situation of the project, find the project interface request entry, which can be the interceptor, AOP of the Controller layer, token verification, etc., and add the following line of code:
MDC.put("trace_uuid", UUID.randomUUID().toString());
Original link: https://blog.csdn.net/qq_36599564/article/details/99947049
However, the specific implementation has not been explained yet.
1. Web request to print uuid
You can use interceptors, Controller layer AOP, token verification, etc. I use interceptors to implement it here.
1. Define an interceptor
import org.slf4j.MDC; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.UUID; /** * Link ID interceptor * */ public class TraceIdInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { MDC.put("trace_uuid", UUID.randomUUID().toString()); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // Do nothing } }
2. Configure interceptor
import cn.quant_cloud.ly.interceptor.TraceIdInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * web configuration class * */ @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new TraceIdInterceptor()); } }
2. Thread pool unified configuration printing UUID
What I actually configured here is Spring Boot’s schdule thread pool, and it is the same when converted to other thread pools.
import org.slf4j.MDC; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import javax.validation.constraints.NotNull; import java.util.UUID; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; /** * Scheduled task configuration class * */ @EnableScheduling @Configuration public class ScheduleConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { //Open a thread scheduling pool ThreadPoolTaskScheduler taskScheduler = new CustomerThreadPoolTaskScheduler(); //Set the thread pool size to 1: prevent multiple scheduled tasks from executing concurrently taskScheduler.setPoolSize(1); taskScheduler.initialize(); taskRegistrar.setTaskScheduler(taskScheduler); } public static class CustomerThreadPoolTaskScheduler extends ThreadPoolTaskScheduler { @Override protected ScheduledExecutorService createExecutor(int poolSize, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) { return new CustomerScheduledExecutorService(poolSize, threadFactory, rejectedExecutionHandler); } } public static class CustomerScheduledExecutorService extends ScheduledThreadPoolExecutor { @Override protected void beforeExecute(Thread t, Runnable r) { //Bind the link tracking ID to the thread context before execution MDC.put("trace_uuid", UUID.randomUUID().toString()); } @Override protected void afterExecute(Runnable r, Throwable t) { //Clear link tracking ID after execution MDC.remove("trace_uuid"); } public CustomerScheduledExecutorService(int corePoolSize, @NotNull ThreadFactory threadFactory, @NotNull RejectedExecutionHandler handler) { super(corePoolSize, threadFactory, handler); } } }