日志写入自定义参数,MDC写入参数
获取
%X{aop01}
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %X{aop01}[ %thread ] - [ %-5level ] [ %logger{50}.%M : %line ] - %msg%n</pattern>
private Map<String, String> COPY_OF_CONTEXT_MAP = MDC.getCopyOfContextMap();
public Map<String, String> getMDCMap(){
if(Objects.isNull(COPY_OF_CONTEXT_MAP)){
COPY_OF_CONTEXT_MAP=MDC.getCopyOfContextMap();
return COPY_OF_CONTEXT_MAP;
}
return COPY_OF_CONTEXT_MAP;
}
public void addMDC(String key, String val) {
MDC.put(key, val);
getMDCMap().put(key,val);
}
带入线程池
在子线程下也可以获取到
threadPoolTaskExecutor.execute(() -> {
MDC.setContextMap(COPY_OF_CONTEXT_MAP);
}
});
线程池配置方式
import org.slf4j.MDC; import org.springframework.core.task.TaskDecorator; import java.util.Map; 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(); // 清理MDC } }; } }
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AsyncConfig { @Bean(name = "threadPoolTaskExecutor") public ThreadPoolTaskExecutor threadPoolTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //执行前、执行后-记录mdc请求唯一值,方便查看整个请求链路日志 executor.setTaskDecorator(new MdcTaskDecorator()); // 设置executor的其他属性,如核心线程池大小、最大线程池大小等 executor.initialize(); return executor; } }