栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Springboot MDC traceId日志中打印唯一traceId

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Springboot MDC traceId日志中打印唯一traceId

参考:https://mp.weixin.qq.com/s/3VmgxcoFazMMhnzU8ddnKQ

代码线程池配置
@EnableAsync
@Configuration
public class ThreadPoolConfig {

    
    @Bean(name = "asyncTaskExecutor")
    public ThreadPoolTaskExecutor asyncTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //1: 核心线程数目
        executor.setCorePoolSize(5);
        //2: 指定最大线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(10);
        //3: 队列中最大的数目
        executor.setQueueCapacity(200);
        //4: 线程名称前缀
        executor.setThreadNamePrefix("kap-Thread-");
        //5:当pool已经达到max size的时候,如何处理新任务
        // CallerRunsPolicy: 会在execute 方法的调用线程中运行被拒绝的任务,如果执行程序已关闭,则会丢弃该任务
        // AbortPolicy: 抛出java.util.concurrent.RejectedExecutionException异常
        // DiscardOldestPolicy: 抛弃旧的任务
        // DiscardPolicy: 抛弃当前的任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //6: 线程空闲后的最大存活时间(默认值 60),当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(60);
        //7:线程空闲时间,当线程空闲时间达到keepAliveSeconds(秒)时,线程会退出,直到线程数量等于corePoolSize,如果allowCoreThreadTimeout=true,则会直到线程数量等于0
        executor.setAllowCoreThreadTimeOut(false);
        // 8.设置线程traceId
        executor.setTaskDecorator(new MdcTaskDecorator());
        //
        executor.initialize();

        return executor;
    }
}
异步调用线程设置traceId
public class MdcTaskDecorator implements TaskDecorator{
        
        @Override
        public Runnable decorate(Runnable runnable) {
            Map map = MDC.getCopyOfContextMap();
            return () -> {
                try{
                    MDC.setContextMap(map);
                    runnable.run();
                } finally {
                    MDC.clear();
                }
            };
        }
}
返回对象设置traceId
@Data
@ApiModel(value = "接口返回对象", description = "接口返回对象")
public class Result implements Serializable {

    private static final long serialVersionUID = 1L;

    
    private static final String TRACE_ID = "TRACE_ID";

    
    @ApiModelProperty(value = "成功标志")
    private boolean success = true;

    
    @ApiModelProperty(value = "返回处理消息")
    private String message = "操作成功!";

    
    @ApiModelProperty(value = "返回代码")
    private Integer code = 0;

    
    @ApiModelProperty(value = "返回数据对象")
    private T result;

    private String traceId;

    
    @ApiModelProperty(value = "时间戳")
    private long timestamp = System.currentTimeMillis();

    public Result() {
        this.traceId = MDC.get(TRACE_ID);
    }

	public static  Result OK() {
        Result result = new Result();
        result.setSuccess(true);
        result.setCode(1);
        result.setMessage("成功");
        result.traceId = MDC.get(TRACE_ID);
        return result ;
    }
 }
日志配置添加traceId
			%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}:%L) - [%X{TRACE_ID}] - %msg%n

测试案例采用shiro做安全框架

在shiro的filter添加traceId

@Slf4j
public class JwtFilter extends BasicHttpAuthenticationFilter {

    
    private static final String TRACE_ID = "TRACE_ID";

 
    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String token = httpServletRequest.getHeader("access-token");
        JwtToken jwtToken = new JwtToken(token);
        // 提交给realm进行登录验证,如果错误会抛出异常并被捕获
        getSubject(request, response).login(jwtToken);
        //添加TRACE_ID
        MDC.put(TRACE_ID, UUID.randomUUID().toString());
        return true;
    }
  @Override
    public void destroy() {
        MDC.clear();
    }

}

测试
  @GetMapping("/getLeaderUserLists")
    @ApiOperation(value = "查询领导人员列表", notes = "查询领导人员列表")
    public Result getLeaderUserList() {
  
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserInfoView::getUserIdentity, 2);
        List list = userInfoViewService.list(queryWrapper);
        //异步调用
        CompletableFuture future = 
        CompletableFuture.runAsync(() -> {
            sysUserService.getUserListLikeUserNameVoid("XX");
        },executor);
        return Result.OK(list);
    }

结果

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/336579.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号