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

Golang+Fiber+OpenTelemetry对接Datadog APM:子Span无法生成求助

解决方案:Fiber + OpenTelemetry 子Span不生成问题排查与修复

1. 修正初始化代码的笔误

你的初始化代码里z.resouce是拼写错误,应该是z.resource,这个小错误可能导致资源标识异常,影响Span的正常上报:

sdkTraceProvider := sdkTrace.NewTracerProvider(
    sdkTrace.WithSpanProcessor(batchSpanProcessor), 
    sdkTrace.WithResource(z.resource), // 修正拼写错误
    sdkTrace.WithSampler(sdkTrace.AlwaysSample()),
)

2. 实现正确的Fiber OTel中间件

Fiber的Ctx不是标准context.Context,必须通过中间件完成Trace上下文的提取、根Span创建,并把OTel上下文绑定到请求生命周期中:

import (
    "go.opentelemetry.io/otel"
    "go.opentelemetry.io/otel/propagation"
    "go.opentelemetry.io/otel/trace"
    "github.com/gofiber/fiber/v2"
)

func OTelMiddleware() fiber.Handler {
    tracer := otel.Tracer("fiber-tracer")
    return func(c *fiber.Ctx) error {
        // 从请求头提取Trace上下文
        ctx := otel.GetTextMapPropagator().Extract(c.UserContext(), propagation.HeaderCarrier(c.GetReqHeaders()))
        
        // 创建根Span,关联请求路径
        ctx, span := tracer.Start(ctx, c.Path(), trace.WithSpanKind(trace.SpanKindServer))
        defer span.End()

        // 将带Trace的上下文存入Fiber Ctx,供后续业务逻辑使用
        c.SetUserContext(ctx)
        
        return c.Next()
    }
}

记得在Fiber实例中注册该中间件:

app := fiber.New()
app.Use(OTelMiddleware())

3. 正确创建子Span

业务逻辑中必须从Fiber的UserContext()获取绑定了父Span的上下文,以此衍生子Span:

func SomeBusinessHandler(c *fiber.Ctx) error {
    // 获取携带父Span上下文的context.Context
    ctx := c.UserContext()
    
    // 创建子Span,指定业务操作名称
    tracer := otel.Tracer("business-tracer")
    ctx, span := tracer.Start(ctx, "user-query-operation")
    defer span.End()

    // 执行业务逻辑:比如DB查询、内部函数调用
    // 注意:后续所有需要追踪的操作,都要传递这个ctx,才能继续生成嵌套子Span

    return c.JSON(fiber.Map{"status": "success"})
}

4. 跨组件的Trace传播

如果涉及对外HTTP调用,要把Trace上下文注入请求头,保证链路跨服务延续:

func CallExternalService(ctx context.Context) error {
    req, err := http.NewRequest("GET", "https://external-service.com/api", nil)
    if err != nil {
        return err
    }
    // 将Trace上下文注入请求头
    otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))
    
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    // 处理响应逻辑...
    return nil
}

关键检查项

  • 所有需要追踪的函数必须传递从Fiber获取的上下文,不能用context.Background()这类空上下文。
  • 确保所有Span都通过defer span.End()正确结束,未结束的Span不会被上报到Datadog。
  • 确认newOTLPTracerExporter的配置正确对接了团队提供的OTLP端点(可通过日志排查 exporter 初始化是否成功)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 05:07:08