背景:
隨著業(yè)務(wù)的復(fù)雜化、解耦化,運(yùn)維人員和開發(fā)人員需要對(duì)請(qǐng)求鏈路跟蹤來快速發(fā)現(xiàn)和定位問題,基于應(yīng)用已經(jīng)集成了SkyWalking的前提下,如何通過獲取SkyWalking生成的統(tǒng)一traceId并加入打印日志中,方便開發(fā)人員能夠根據(jù)鏈路ID快速搜索單個(gè)請(qǐng)求的全鏈路日志呢?
基本思路:
trace-id的生成:
結(jié)合apm-toolkit-trace提供的工具類獲取請(qǐng)求的trace-id,前提是應(yīng)用已經(jīng)集成對(duì)接了SkyWalking
trace-id的存放:
一種輕量級(jí)的實(shí)現(xiàn),通過??MDC?機(jī)制,將請(qǐng)求的?trace-id?放入到MDC中,在日志打印時(shí),通過?MDC?中的?trace-id?將同一個(gè)請(qǐng)求的每一條日志串聯(lián)起來。因?yàn)?MDC?是線程隔離且安全的。
trace-id的打印:
通過修改logback.xml配置中pattern增加輸出參數(shù)%X{traceId}來控制。
trace-id存放的觸發(fā)機(jī)制:
通常實(shí)現(xiàn)方式,采用增加日志攔截器的做法,將攔截服務(wù)所有外部請(qǐng)求,在請(qǐng)求前置處理中將生成trace-id并保存入MDC中。
代碼示例:
通用做法-開發(fā)三板斧:依賴、配置、注解與編碼
依賴?
<!-- skywalking依賴包 打印traceid -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.7.0</version>
</dependency>
配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<jmxConfigurator/>
<contextName>logback</contextName>
<springProperty scope="context" name="module_name" source="spring.application.name"/>
<!-- 讀取apollo配置中心設(shè)置的變量 -->
<springProperty scope="context" name="version" source="app.version"/>
<springProperty scope="context" name="env" source="app.env"/>
<timestamp key="log_date" datePattern="yyyy-MM-dd"/>
<!--自定義輸出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - thead=%thread - level=%-5level - class=%logger{20} - token=%X{token} - traceId=%X{traceId} - content=%msg%n</pattern>
</encoder>
</appender>
<!-- 日志輸出級(jí)別 -->
<root level="debug">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
編碼
(1) 自定義攔截器LoggerInterceptor
package com.zzia.demo.interceptor;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
@Component
public class LoggerInterceptor implements HandlerInterceptor {
/**
* @return 返回 true 放行、放回 false 攔截
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("進(jìn)入攔截器,前置通知" + request.getRequestURI());
// 過濾掉確認(rèn)的 options 請(qǐng)求
if ("OPTIONS".equals(request.getMethod())) {
return true;
}
// 單鏈路上下文信息存入MDC
// 請(qǐng)求憑證
String token = request.getHeader("__ub_token");
MDC.put("token", token);
//每次請(qǐng)求生成唯一的請(qǐng)求標(biāo)識(shí),作為內(nèi)部鏈路的日志追蹤標(biāo)識(shí)
MDC.put("traceId", TraceContext.traceId());
// 業(yè)務(wù)身份字段可擴(kuò)展加入
String userId = "123456";
MDC.put("userId", userId);
if (token != null) {
return true;
}
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("后置通知");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("最終通知");
MDC.clear();
}
}
(2) 注冊(cè)攔截器
package com.zzia.demo.interceptor;
import org.springframework.beans.factory.annotation.Autowired;
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 MyLoggerConfigurer implements WebMvcConfigurer {
@Autowired
LoggerInterceptor myInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor) // 添加自定義攔截器
.excludePathPatterns("/index") // 設(shè)置放行路徑
.addPathPatterns("/**"); // 設(shè)置攔截路徑
}
}
演示效果:
文章來源:http://www.zghlxwxcb.cn/news/detail-613290.html
說明:本示例的前置準(zhǔn)備參見文章Spring boot 集成Skywalking_幽幽之心的博客-CSDN博客?文章來源地址http://www.zghlxwxcb.cn/news/detail-613290.html
到了這里,關(guān)于Spring boot結(jié)合SkyWalking-Trace工具類實(shí)現(xiàn)日志打印請(qǐng)求鏈路traceid的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!