国产毛多水多高潮高清,久热这里只有精品视频6,国内精品久久久久久久久电影网,国产男同志CHINA69,精品999日本久久久影院,人人妻人人澡人人爽人人精品,亚洲中文无码永久免

基于Slf4j的MDC实现日志链路串联-尊胜娱乐指定

基于Slf4j的MDC实现日志链路串联

2026-01-17 03:07:47投稿人:愛游戲APP官網(wǎng)下載IOS版(四川)有限公司圍觀917363 評論

基于Slf4j的MDC實現(xiàn)日志鏈路串聯(lián)

一 、問題背景

為了方便運維日常定位排查問題時,使用traceId查詢?nèi)罩緯r可以完整的查看當前業(yè)務請求的完整日志鏈路,需使用traceId(日志跟蹤號)將日志串聯(lián)起來。

系統(tǒng)采用LogBack日志組件,在輸出日志時輸出_traceId日志跟蹤號  ,logback.xml配置如下:

../log/${ ServerName}/${ AppName}.log../log/${ ServerName}/${ AppName}.log.%d{ yyyy-MM-dd}        7%d{ HH:mm:ss.SSS} %-5level [%.15thread][%X{ _traceId}] %logger{ 36} - %.-4096msg%n

公司系統(tǒng)采用分布式架構,從接收到請求到業(yè)務處理完成并返回 ,涉及SpringMVC入口  、服務間dubbo調(diào)用、基于RocketMQ實現(xiàn)的業(yè)務解耦、以及來自第三方渠道的http通知回調(diào)。

現(xiàn)在的問題是從業(yè)務請求入口到返回業(yè)務響應  ,如何使用同一traceId將日志做串聯(lián)?

Slf4j的MDC機制提供了上述問題的解決方案 。

二 、解決方案

在介紹具體解決方案之前 ,首先介紹下Slf4j日志框架的MDC機制。映射診斷上下文(Mapped Diagnostic Context,簡稱MDC)可以簡單理解為當前日志線程的上下文,也是一個k-v格式的map結構 。

當服務器幾乎同時處理多個請求時,日志輸出通常是交錯的 ,而MDC是基于每個線程進行管理的,子線程自動繼承其父線程的MDC的副本 ??梢酝ㄟ^往MDC里塞入traceId ,達到串聯(lián)日志的目的 。

以下為MDC填充獲取traceId方法:

public final static String TRACE_ID = "_traceId";static private String generateTraceId() {     return UUID.randomUUID().toString().replaceAll("-", "");}public static String getTraceId() {     return MDC.get(TRACE_ID);}public static void setTraceId(String traceId) {     MDC.put(TRACE_ID, traceId);}public static void clearTrace() {     MDC.remove(TRACE_ID);}public static void initTrace() {     String traceId = generateTraceId();    setTraceId(traceId);}

2.1 、接收http請求時的日志鏈路串聯(lián)

解決思路 :可以從HttpServletRequest獲取traceId并塞到MDC中 。

具體如下 :

public static void initTraceFromRequest(HttpServletRequest request) {     String traceId;    // 從前端表單提交里獲取traceId    traceId = request.getParameter(TRACE_ID);    if (StringUtils.isNotBlank(traceId)) {         setTraceId(traceId, request);        return;    }    // 從forward后端轉(zhuǎn)發(fā)請求里獲取traceId    traceId = (String) request.getAttribute(TRACE_ID);    if (StringUtils.isNotBlank(traceId)) {         setTraceId(traceId, request);        return;    }    // 從請求url路徑中里獲取traceId    Map pathVariables = (Map) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);    if (pathVariables != null) {         traceId = (String) pathVariables.get(TRACE_ID);    }    if (StringUtils.isNotBlank(traceId)) {         setTraceId(traceId, request);        return;    }    // 以上都獲取不到的話