fix: 修复ContextInterceptor响应头未设置traceId和spanId的问题

- 新增HEADER_SPAN_ID常量
- preHandle中生成SpanId并设置到响应头
- response.setHeader(HEADER_TRACE_ID, traceId)
- response.setHeader(HEADER_SPAN_ID, spanId)
This commit is contained in:
zhangjf 2026-02-20 11:52:00 +08:00
parent 9b3b3538c8
commit 2c7d304408

View File

@ -14,7 +14,7 @@ import org.springframework.web.servlet.HandlerInterceptor;
/** /**
* 租户和用户上下文拦截器 * 租户和用户上下文拦截器
* 从HTTP Header中提取租户ID用户ID请求来源等信息设置到ThreadLocal中 * 从HTTP Header中提取租户ID用户ID请求来源等信息设置到ThreadLocal中
* 同时记录请求来源和链路耗时信息 * 同时记录请求来源和链路耗时信息并在响应头中返回traceId和spanId
*/ */
@Component @Component
public class ContextInterceptor implements HandlerInterceptor { public class ContextInterceptor implements HandlerInterceptor {
@ -26,6 +26,7 @@ public class ContextInterceptor implements HandlerInterceptor {
public static final String HEADER_TENANT_ID = "X-Tenant-Id"; public static final String HEADER_TENANT_ID = "X-Tenant-Id";
public static final String HEADER_USER_ID = "X-User-Id"; public static final String HEADER_USER_ID = "X-User-Id";
public static final String HEADER_TRACE_ID = "X-Trace-Id"; public static final String HEADER_TRACE_ID = "X-Trace-Id";
public static final String HEADER_SPAN_ID = "X-Span-Id";
/** /**
* 请求开始时间属性Key * 请求开始时间属性Key
@ -80,19 +81,31 @@ public class ContextInterceptor implements HandlerInterceptor {
} }
} }
// 提取 TraceId如不存在后续会在需要时自动生成 // 提取或生成 TraceId全链路唯一标识
String traceId = request.getHeader(HEADER_TRACE_ID); String traceId = request.getHeader(HEADER_TRACE_ID);
if (traceId != null && !traceId.isEmpty()) { if (traceId != null && !traceId.isEmpty()) {
TraceContextHolder.setTraceId(traceId); TraceContextHolder.setTraceId(traceId);
} else {
traceId = TraceContextHolder.getOrCreateTraceId();
} }
// 记录请求追踪日志 // 生成 SpanId当前服务处理标识每个请求唯一
String spanId = TraceContextHolder.getOrCreateSpanId();
// 在响应头中返回 traceId spanId方便客户端追踪
response.setHeader(HEADER_TRACE_ID, traceId);
response.setHeader(HEADER_SPAN_ID, spanId);
// 记录请求追踪日志使用spanId作为索引ID
if (sourceService != null && chainDuration != null) { if (sourceService != null && chainDuration != null) {
logger.info("[Trace] {} -> {} | traceId={} | chainTime={}ms | path={}", logger.info("[{}] {} -> {} | traceId={} | chainTime={}ms | path={}",
sourceService, serviceName, traceId, chainDuration, request.getRequestURI()); spanId, sourceService, serviceName, traceId, chainDuration, request.getRequestURI());
} else if (sourceService != null) { } else if (sourceService != null) {
logger.info("[Trace] {} -> {} | traceId={} | path={}", logger.info("[{}] {} -> {} | traceId={} | path={}",
sourceService, serviceName, traceId, request.getRequestURI()); spanId, sourceService, serviceName, traceId, request.getRequestURI());
} else {
logger.info("[{}] external -> {} | traceId={} | path={}",
spanId, serviceName, traceId, request.getRequestURI());
} }
return true; return true;
@ -103,12 +116,15 @@ public class ContextInterceptor implements HandlerInterceptor {
Object handler, Exception ex) { Object handler, Exception ex) {
// 计算当前服务处理耗时 // 计算当前服务处理耗时
Long startTime = (Long) request.getAttribute(ATTR_START_TIME); Long startTime = (Long) request.getAttribute(ATTR_START_TIME);
String spanId = TraceContextHolder.getSpanId();
String traceId = TraceContextHolder.getTraceId();
String sourceService = request.getHeader(HEADER_SOURCE_SERVICE);
if (startTime != null) { if (startTime != null) {
long duration = System.currentTimeMillis() - startTime; long duration = System.currentTimeMillis() - startTime;
String traceId = request.getHeader(HEADER_TRACE_ID);
String sourceService = request.getHeader(HEADER_SOURCE_SERVICE);
logger.debug("[Trace] {} -> {} | traceId={} | processTime={}ms | status={}", logger.debug("[{}] {} -> {} | traceId={} | processTime={}ms | status={}",
spanId != null ? spanId : "unknown",
sourceService != null ? sourceService : "external", sourceService != null ? sourceService : "external",
serviceName, serviceName,
traceId, traceId,