You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Spring Cloud Sleuth Trace ID填入spring-hateoas中VndError的logRef字段?

在Spring Hateoas的VndError中填充Spring Cloud Sleuth Trace ID的正确姿势

我来帮你梳理下这个问题的解决方案:

有没有官方实现方式?

目前Spring生态里并没有直接把Sleuth Trace ID自动注入VndError的开箱即用官方功能,不过有标准的推荐做法,不用自己造复杂的轮子。

两种获取Trace ID方式的对比

你代码里的两种方式都能拿到Trace ID,但有细微差别:

  • 从MDC获取:MDC.get("X-B3-TraceId"),这种方式很简洁,因为Sleuth会自动把Trace ID和Span ID绑定到当前请求线程的MDC中。但要注意,这种方式依赖线程上下文,如果是在异步线程处理异常的场景下,MDC上下文可能丢失,导致拿不到Trace ID。不过在你的@ExceptionHandler方法里,因为是处理当前请求的同步异常,线程上下文是稳定的,所以也能正常工作。
  • 通过Tracer API获取:tracer.currentSpan().context().traceIdString(),这是Sleuth官方推荐的方式,可靠性更高。Tracer是Sleuth的核心组件,能准确追踪当前请求的Span上下文,哪怕是在异步场景下也能通过上下文传递拿到正确的Trace ID。而且建议加上空判断,避免当没有Span(比如非请求触发的异常)时出现空指针问题。

推荐的优化代码

结合可靠性和简洁性,推荐你用Tracer的方式,同时做个空安全处理:

@ControllerAdvice
class GlobalExceptionHandler {
    @Autowired
    private lateinit var tracer: Tracer

    @ExceptionHandler(LocalException::class)
    fun handleLocalException(e: LocalException): ResponseEntity<VndErrors.VndError> {
        // 空安全获取Trace ID,避免NPE
        val traceId = tracer.currentSpan()?.context()?.traceIdString() ?: "unknown-trace-id"
        // 同时给message加默认值,避免null
        val error = VndErrors.VndError(traceId, e.message ?: "服务器内部错误")
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error)
    }
}

额外小建议

如果你的项目里有多个异常处理方法,不想重复写Trace ID的获取逻辑,可以封装一个简单的工具类,比如:

@Component
class TraceIdProvider(private val tracer: Tracer) {
    fun getCurrentTraceId(): String {
        return tracer.currentSpan()?.context()?.traceIdString() ?: "unknown-trace-id"
    }
}

然后在@ControllerAdvice里注入这个工具类调用就行,代码更整洁。

内容的提问来源于stack exchange,提问作者HughWPHamill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:58:30