如何在Spring Boot 3与Micrometer中创建独立新Trace
独立新Trace的实现需求
在部分场景下,需要创建完全独立于父TraceContext或ObservationContext的新Trace。比如某API启动100个项的处理流程,每个项包含Feign调用、Spring Cloud Stream跳转等操作,Spring会自动基于API生成ObservationContext,导致API调用和所有项的处理共用同一个Trace。用Kibana排查错误时,按traceId过滤会返回所有项的日志,没法有效关联单个项的问题;spanId也因为频繁创建新Span,无法用来关联单个项的完整流程。
因此在特定可控场景下,希望为每个项创建独立的新Trace,即便丢失和原API调用的关联也可以接受。尝试过ObservationRegistry、ContextSnapshot等方式,但代码始终会继承父ObservationContext或TracingContext。
理想的执行流程是:
- 备份当前链路上下文
- 从零创建新的链路上下文
- 使用新上下文执行目标代码
- 恢复原上下文
之前用Sleuth可以轻松实现,但现在切换到新的观测框架后遇到了困难。期望实现一个runWithNewTrace方法,示例代码如下:
List<String> traceIds = new ArrayList<>(); Observation.createNotStarted("test.traceObservation", observationRegistry) // 1 .contextualName("create test with Observation API") // 2 .observe(() -> { traceIds.add(getCurrentTraceId()); runWithNewTrace("test", () -> traceIds.add(getCurrentTraceId())); traceIds.add(getCurrentTraceId()); }); String traceIdBefore = traceIds.get(0); String traceIdThatShouldBeDifferent = traceIds.get(1); String traceIdAfterThatShouldBeSameAsBefore = traceIds.get(2); assertThat(traceIdThatShouldBeDifferent).isNotNull().isNotEqualTo("no-trace"); assertThat(traceIdBefore).isNotEqualTo(traceIdThatShouldBeDifferent); assertThat(traceIdBefore).isEqualTo(traceIdAfterThatShouldBeSameAsBefore);
getCurrentTraceId方法的实现如下:
public String getCurrentTraceId() { Span currentSpan = tracer.currentSpan(); if (currentSpan != null && currentSpan.context() != null) { return currentSpan.context().traceId(); } return "no-trace"; }
内容的提问来源于stack exchange,提问作者Sébastien Nussbaumer
相关产品推荐
相关产品推荐

