Logback 實現日志鏈路追蹤


本文為博主原創,未經允許不得轉載:

  在開發過程中,經常會使用log記錄一下當前請求的參數,過程和結果,以便幫助定位問題。在並發量下的情況下,日志打印不會劇增,可以很快就能通過打印的日志查看執行的情況。但是在高並發大量請求的場景下,日志也會頻繁打印,刷新,通過查看日志來定位問題時就會變得很難,因為無法確定打印的日志是哪一條請求時打印的,從而影響問題的定位速度。

  一種輕量級的實現,通過  MDC 機制,將請求的 trace-id 放入到MDC中,在日志打印時,通過 MDC 中的 trace-id 將同一個請求的每一條日志串聯起來。因為 MDC 是線程隔離且安全的。

  logback MDC 實現日志追蹤實現:

  1. 在請求剛到達網關層時,添加一個過濾器,每個請求在過濾器時,在 logback 的MDC 中放入 trace-id。

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.slf4j.MDC;

import javax.servlet.*;
import java.io.IOException;

public class LogFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 使用雪花算法生成一個請求Id
        String traceId = Long.toString(IdWorker.getId());
        MDC.put("trace-id",traceId);
    }
}

  2. 在logback.xml 中配置 log 打印格式,並打印 trace-id

 <!-- 控制台輸出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder charset="UTF-8">
            <!-- 輸出日志記錄格式,並打印 trace-id -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%trace-id] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    logback 中也可以使用占位符%X{ }來占位,替換到對應的 MDC 中 key 的值

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> 
  <layout>
    <Pattern>%X{trace-id}- %m%n</Pattern>
  </layout> 
</appender>

 

  3. logback mdc實現原理

  logback的實現類LogbackMDCAdapter利用的ThreadLocal技術保證了每個請求線程保有自己的MDC環境變量。其使用了裝飾者模式。

  MDCAdapter有三個實現類,BasicMDCAdapter、LogbackMDCAdapter,NOPMDCAdapter。Logback使用的是LogbackMDCAdapter。

                         

 

   LogbackMDCAdapter 中使用的時 ThreadLocal 進行線程隔離實現的。

                           

 

     附:在日志打印優化以及方便日志定位的過程中,也可以使用 AOP,對 controller ,service 等進行統一打印,打印每一個方法的調用請求參數,開始時間,結束時間,耗時等。這會大大提高日志的價值。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM