基於Slf4j MDC和Spring MVC的日誌鏈路跟蹤

  • 背景

1.在日常查日誌時,各種日誌交錯在一起,無法快速定位問題,如果有每個請求都擁有一個唯一標識,那grep起來就方便多了;

2.分佈式系統中需要定位整個鏈路,是上游系統出問題了,或者下游系統有沒有收到請求;

  • 方案

Slf4j是我們常用的日誌門面,它服務於Logback和log4j等日誌框架,其中有一個重要特性是MDC(Mapped Diagnostic Contexts );

顧名思義,其目的是爲了便於我們診斷線上問題而出現的方法工具類,使用ThreadLocal思想在線程上下文中維護變量;

比如配置文件logback.xml 中配置了%X{key},則後臺日誌打印出對應的 key 的值;

文檔地址:https://logback.qos.ch/manual/mdc.html

  • 應用

1.通過日誌配置文件加traceId變量(%X{traceId})
如:${APP_NAME}: %d{yyyy-MM-dd HH:mm:ss.SSS} [%X{traceId}] [%thread] %p - %c %m%n

2.定義Filter(也可以用Spring MVC的攔截器),這裏提供下關鍵方法doFilter:
doFilter
注:在進去請求前使用MDC.put將traceId放入線程變量,最後finally刪除變量,這裏traceId生成算法採用UUID,還有比如線程名+時間戳方式,實用就行。

3.在web.xml中聲明Filter
聲明Filter
4.結果展示
示例:Controller裏調用了Service1的doSomething方法,而Service1又分別調用了Service2和Service3的doSomething方法,那麼形式的日誌如下:
結果展示
所以通過grep 45c5827048ab4d61a81eed0caff35dce就可以定位整個調用過程

5.應用於分佈式系統
包裝上游系統的請求,將traceId放入header中,並在下游系統定義Filter解析header,然後使用MDC工具類將traceId放入線程變量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章