当前位置: 首页 > ops >正文

如何在 Logback 日志框架中加入链路 ID

在 Logback 日志框架中加入链路 ID,能有效将同一条链路的日志串联起来,便于追踪和排查问题。

1. 生成和管理链路 ID

要保证在整个请求链路里都能获取到链路 ID,可借助 ThreadLocal 来实现。以下是一个简单的工具类示例:

import java.util.UUID;public class TraceIdUtil {private static final ThreadLocal<String> traceIdHolder = new ThreadLocal<>();// 生成链路 IDpublic static String generateTraceId() {String traceId = UUID.randomUUID().toString();traceIdHolder.set(traceId);return traceId;}// 获取链路 IDpublic static String getTraceId() {return traceIdHolder.get();}// 清除链路 IDpublic static void clearTraceId() {traceIdHolder.remove();}
}

2. 在请求入口生成链路 ID

可使用拦截器、过滤器或者 AOP 来在请求进入时生成链路 ID。这里以拦截器为例:

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class TraceIdInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 生成链路 IDString traceId = TraceIdUtil.generateTraceId();// 可将链路 ID 放入响应头,方便下游服务获取response.setHeader("Trace-Id", traceId);return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 请求处理完成后清除链路 IDTraceIdUtil.clearTraceId();}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 请求完成后再次清除链路 ID,确保不会有残留TraceIdUtil.clearTraceId();}
}

同时,要在 Spring Boot 中配置该拦截器:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new TraceIdInterceptor()).addPathPatterns("/**"); // 拦截所有请求}
}

3. 配置 Logback 日志格式

logback.xml 配置文件里,使用 %X{traceId} 来获取并展示链路 ID。示例配置如下:

<configuration><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><!-- 配置日志输出格式,加入链路 ID --><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{traceId}] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="info"><appender-ref ref="CONSOLE" /></root>
</configuration>

在上述配置中,%X{traceId} 用于输出存储在 MDC(Mapped Diagnostic Context)中的链路 ID。

4. 在代码中使用 MDC 存储链路 ID

在生成链路 ID 后,要把它存储到 MDC 中,这样 Logback 才能正确获取。可在拦截器中添加如下代码:

import org.slf4j.MDC;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class TraceIdInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 生成链路 IDString traceId = TraceIdUtil.generateTraceId();// 将链路 ID 存入 MDCMDC.put("traceId", traceId);// 可将链路 ID 放入响应头,方便下游服务获取response.setHeader("Trace-Id", traceId);return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 请求处理完成后清除 MDC 中的链路 IDMDC.remove("traceId");// 请求处理完成后清除链路 IDTraceIdUtil.clearTraceId();}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 请求完成后再次清除 MDC 中的链路 ID,确保不会有残留MDC.remove("traceId");// 请求完成后再次清除链路 ID,确保不会有残留TraceIdUtil.clearTraceId();}
}

通过以上步骤,就能在 Logback 日志框架中加入链路 ID,使每条日志都包含对应的链路 ID,方便进行链路追踪和问题排查。

在这里插入图片描述

http://www.xdnf.cn/news/4794.html

相关文章:

  • 嵌入式开发学习日志Day16
  • MAC电脑日期与时间问题和定位不能正常使用问题
  • mysql数据库体验
  • 国标GB28181软件EasyGBS雪亮工程打造智能高效的视频监控新体系
  • git的常用命令详解
  • 【redis】分片方案
  • 一文读懂Python之requests模块(36)
  • 扣子创建一个应用
  • 基于vm加密的php逆向分析
  • verilog循环仿真
  • Spark处理过程-案例数据清洗
  • Linux命令行参数注入详解
  • 深入剖析ThreadLocal:原理、应用与最佳实践
  • 笔试强训——第七周
  • 前端三大件---CSS
  • 塔能空压系统节能方案:为华东某电子厂降耗赋能
  • JavaSE核心知识点02面向对象编程02-02(封装、继承、多态)
  • 基于LLM的全自动视频生成工具:MoneyPrinterTurbo 技术解析
  • CAN总线通讯接口卡:工业通信的核心桥梁
  • wails3学习-runtime:Window无边框设置
  • 数据结构(四)——栈的应用—数制转换
  • Java线程阻塞方法LockSupport.park()/Thread.sleep()/Object.wait()详解:原理、区别
  • java实战(第六篇):统计投票信息
  • [特殊字符]【深圳金融科技交流会】AI大模型如何重塑资管新生态?一线实战干货来了!
  • 极简远程革命:打破公网桎梏,重塑数字生活新体验
  • Vue 3.0中Treeshaking特性
  • Nacos源码—6.Nacos升级gRPC分析二
  • 从SiC到数字孪生:PSR芯片的技术迭代与未来布局
  • windows10 系统显示mov文件格式缩略图
  • 使用Hyper-V 安装Windows11操作系统