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

SpringBoot2.7+Sleuth3.1:Logbook集成Micrometer Tracing传Trace ID

在Spring Boot 2.7.x + Spring Cloud Sleuth 3.1.x中集成Micrometer Tracing实现Logbook Trace ID传递

合规性说明

完全合规。Spring Cloud Sleuth 3.1.x已经全面基于Micrometer Tracing重构,官方明确推荐使用Micrometer Tracing替代原有的Sleuth内部追踪API,废弃ReactorNettyHttpTracing正是这一迭代的一部分,因此改用Micrometer Tracing实现Trace ID在Logbook中的传递是符合官方规范的方案。

集成步骤与示例

1. 依赖配置

调整项目依赖(以Maven为例),确保引入兼容版本的Sleuth、Micrometer Tracing桥接包和Logbook:

<dependencies>
    <!-- Spring Cloud Sleuth 核心依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-sleuth</artifactId>
        <version>3.1.8</version>
    </dependency>
    <!-- Micrometer Tracing Brave桥接(Sleuth 3.1.x默认使用Brave) -->
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-tracing-bridge-brave</artifactId>
    </dependency>
    <!-- Logbook Spring Boot Starter -->
    <dependency>
        <groupId>org.zalando</groupId>
        <artifactId>logbook-spring-boot-starter</artifactId>
        <version>2.24.0</version>
    </dependency>
</dependencies>

2. 自定义Logbook增强器(注入Trace ID)

通过自定义Logbook的Formatter或Sink,从Micrometer Tracing的Tracer中获取当前Trace/Span ID并追加到日志中:

示例1:自定义Formatter(直接在日志内容中追加Trace ID)
import io.micrometer.tracing.Tracer;
import org.zalando.logbook.Formatter;
import org.zalando.logbook.HttpRequest;
import org.zalando.logbook.HttpResponse;
import org.springframework.stereotype.Component;

@Component
public class TraceIdEnhancingFormatter implements Formatter {

    private final Tracer tracer;
    private final Formatter delegate;

    // 构造注入默认Formatter和Tracer
    public TraceIdEnhancingFormatter(Tracer tracer, Formatter delegate) {
        this.tracer = tracer;
        this.delegate = delegate;
    }

    @Override
    public String format(HttpRequest request) {
        return enrichLogWithTraceId(delegate.format(request));
    }

    @Override
    public String format(HttpRequest request, HttpResponse response) {
        return enrichLogWithTraceId(delegate.format(request, response));
    }

    private String enrichLogWithTraceId(String originalLog) {
        return tracer.currentSpan()
                .map(span -> String.format("[traceId=%s, spanId=%s] %s",
                        span.context().traceId(), span.context().spanId(), originalLog))
                .orElse(originalLog);
    }
}
示例2:自定义Sink(将Trace ID注入请求头)

如果需要在Logbook记录的请求头中携带Trace ID,可以实现Sink:

import io.micrometer.tracing.Tracer;
import org.zalando.logbook.CorrelationId;
import org.zalando.logbook.HttpRequest;
import org.zalando.logbook.HttpResponse;
import org.zalando.logbook.Sink;
import org.springframework.stereotype.Component;

@Component
public class TraceIdInjectingSink implements Sink {

    private final Tracer tracer;
    private final Sink delegate;

    public TraceIdInjectingSink(Tracer tracer, Sink delegate) {
        this.tracer = tracer;
        this.delegate = delegate;
    }

    @Override
    public void write(HttpRequest request, CorrelationId correlationId) {
        injectTraceId(request);
        delegate.write(request, correlationId);
    }

    @Override
    public void write(HttpRequest request, HttpResponse response, CorrelationId correlationId) {
        injectTraceId(request);
        delegate.write(request, response, correlationId);
    }

    private void injectTraceId(HttpRequest request) {
        tracer.currentSpan().ifPresent(span -> {
            request.withHeaders(headers -> headers
                    .add("X-B3-TraceId", span.context().traceId())
                    .add("X-B3-SpanId", span.context().spanId()));
        });
    }
}

3. 配置Logbook使用自定义增强器

创建配置类,将自定义的Formatter或Sink注册到Logbook构建器中:

import org.zalando.logbook.Logbook;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class LogbookTracingConfig {

    @Bean
    public Logbook logbook(TraceIdEnhancingFormatter formatter, Logbook.Builder builder) {
        return builder.formatter(formatter).build();
    }

    // 如果使用Sink,替换为:
    // @Bean
    // public Logbook logbook(TraceIdInjectingSink sink, Logbook.Builder builder) {
    //     return builder.sink(sink).build();
    // }
}

4. 验证

启动应用后发起HTTP请求,查看Logbook输出的日志,即可看到包含traceId和spanId的内容,示例日志输出:

[traceId=abc123def456, spanId=789ghi] Request: GET /api/test
Headers: {Host=localhost:8080, User-Agent=Mozilla/5.0}

注意事项

  • 确保Spring Cloud Sleuth 3.1.x版本与Spring Boot 2.7.x兼容(3.1.x系列专为Boot 2.7.x设计)
  • 若需切换到OpenTelemetry作为追踪实现,可替换micrometer-tracing-bridge-brave为micrometer-tracing-bridge-otel
  • Logbook版本需选择与Spring Boot 2.7.x兼容的分支(2.x系列均兼容)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 20:45:34