logback输出日志区分所属线程:方便运维排查问题

logback输出日志区分所属线程:方便运维排查问题

背景

业务上,当同一个请求日志很多,我们需要查看,某一次请求的上下文日志信息,怎么办?

先来看看我们的请求过程:

不同用户发起同一个请求 -----> web容器(tomcat) -----> 从线程池拿到一个线程,处理具体一个用户的请求 -----> 我们的业务代码,输出日志

那就在每行日志输出上,增加代表这个线程,会话的信息,方案如下:

1. 输出线程id
2. 输出自己生成的随机字符,如uuid

先来看第一种方案: 线程是从线程池拿到,id是可能会重复,不符合我们的需求。那么只有第二中方案符合我们的需求了。

输出自己生成的随机字符

slf4j为我们提供了MCD工具类,可以让我们放一些变量值到日志中输出。

自定义拦截器,设置MCD

生成每次请求的唯一标识

/**
 * @author xuelongjiang
 * @description logback拦截器
 **/
public class LogInterceptor implements HandlerInterceptor {

    public static final String REQUESTUUID = "REQUEST_UUID";

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        String token = UUID.randomUUID().toString().replace("-", "").toUpperCase();
        MDC.put(REQUESTUUID, token);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                           Object o, ModelAndView modelAndView) throws Exception {
        // nothing
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest,
                                HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        MDC.remove(REQUESTUUID);
    }
}

HandlerInterceptor业务处理器拦截器,给我们提供了三个方法:

1.preHandle:在业务处理器请求之前被调用。预处理可以可以进行编码控制、安全控制、权限校验等
2.postHandle:在业务处理器处理请求完成之后,在生成视图之前执行。
3.afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。

设置拦截所有请求

@Configuration
public class WebAppconfigure implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry interceptorRegistry) {
        interceptorRegistry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");
        return;
    }
}

logback日志输出增加请求唯一标识

 <encoder>
            <pattern>
				%date{yyyy-MM-dd HH:mm:ss.SSS} | %thread | %logger{56} | %-5level | %X{HOST_IP} | %X{USER_NAME} | %X{REQUEST_UUID} | %X{REQUEST_URL} | %msg%n
            pattern>
        encoder>

参考

https://blog.csdn.net/zhibo_lv/article/details/81699360

你可能感兴趣的:(运维,java,spring,观察者模式,java)