slf4j有个MDC的类,是ThreadLocal的实现,保存在这里的变量会绑定到某个请求线程,于是在该请求的线程里的日志代码都可以使用设入的变量。
这个是可选项,用于生成唯一uid,我人懒,就直接用这个工具,你们要自定义uid格式的,就可以不用导入。
-
- <dependency>
- <groupId>cn.hutoolgroupId>
- <artifactId>hutool-allartifactId>
- <version>5.7.20version>
- dependency>
因为要给每一个请求都利用所以建议利用MDC绑定traceId,所以需要用拦截器拦截每一个请求。
先给设置一个拦截器配置InterceptorConfig.class并实现重写WebMvcConfigurer,如下:
- @Configuration
- public class InterceptorConfig implements WebMvcConfigurer {
-
- /**
- * http请求拦截器
- * @param registry
- */
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
-
- registry.addInterceptor(new TraceIdInterceptor());
- }
- }
里面的new TraceIdInterceptor()就是我们的核心配置类了,用于MDC绑定traceId到线程中,首先,新建一个TraceIdInterceptor.class,代码及注释如下:
- @Component
- public class TraceIdInterceptor implements HandlerInterceptor {
-
- /**
- * preHandle为请求前拦截
- */
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-
- // 在日志框架中的MDC中添加请求的唯一标识(用于返回接口及保存mysql)
- String traceId = String.valueOf(UUID.randomUUID());
-
- // 绑定key值到线程中
- MDC.put("traceId", traceId);
- response.addHeader("traceId",traceId);
-
- // 继续执行接口请求
- return true;
- }
- }
然后通过【MDC.get("traceId")】实现获取traceId,这个可以用在统一返回的结果包装类里,如下:
- /**
- * 接口返回统一包装
- */
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- public class Result {
- private String traceId;
- private Integer code;
- private String msg;
- private Object data;
-
- /**
- * 成功,且返回体有数据
- * @param code
- * @param msg
- * @param data
- * @return
- */
- public static Result success(Integer code, String msg, Object data) {
-
- // 获取MDC中绑定的traceId
- String traceId = MDC.get("traceId");
- return new Result(traceId, code, msg, data);
- }
-
- /**
- * 成功,但返回体没数据
- * @param code
- * @param msg
- * @return
- */
- public static Result success(Integer code, String msg) {
-
- // 获取MDC中绑定的traceId
- String traceId = MDC.get("traceId");
- return new Result(traceId, code, msg, null);
- }
- }