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

Golang中OpenTelemetry Exporter部分成功问题求助

问题分析与解决

核心原因

你遇到的OTLP partial success: empty message (0 spans rejected)错误,结合代码来看,主要是以下几个配置遗漏或错误导致的:

  • 未正确传递资源配置:创建了Resource对象但未传入TracerProvider,OpenTelemetry要求服务名称等核心资源属性必须明确设置,否则可能导致Span无法被Collector正常识别或接收。
  • 未触发TracerProvider关闭逻辑:BatchSpanProcessor采用异步批量发送机制,程序结束时若不主动调用Shutdown,缓存的Span会直接被丢弃,无法发送到Collector。
  • 采样器配置被注释:虽然默认采样器为ParentBased(AlwaysOn),但显式配置AlwaysSample能确保测试场景下所有Span都被采样发送,避免潜在的采样逻辑异常。

修复步骤

1. 完善TracerProvider的资源与采样器配置

修改initProvider函数,将创建的Resource传入TracerProvider,并启用强制采样:

func initProvider() func() {
    ctx := context.Background()

    // 保存创建的resource变量
    res, err := resource.New(ctx,
        resource.WithAttributes(
            semconv.ServiceNameKey.String("test-service"),
        ),
    )
    handleErr(err, "failed to create resource")
    
    traceExporter, err := otlptracehttp.New(ctx,
        otlptracehttp.WithInsecure(),
        otlptracehttp.WithEndpoint("localhost:4318"),
    )
    handleErr(err, "failed to create trace exporter")

    bsp := sdktrace.NewBatchSpanProcessor(traceExporter)
    tracerProvider := sdktrace.NewTracerProvider(
        // 启用AlwaysSample采样器,确保所有Span都被发送
        sdktrace.WithSampler(sdktrace.AlwaysSample()),
        // 将resource传入TracerProvider
        sdktrace.WithResource(res),
        sdktrace.WithSpanProcessor(bsp),
    )

    otel.SetTracerProvider(tracerProvider)
    // otel.SetTextMapPropagator(propagation.TraceContext{})
    return func() {
        handleErr(tracerProvider.Shutdown(ctx), "failed to shutdown TracerProvider")
    }
}

2. 恢复Shutdown方法调用

在main函数中恢复Shutdown的调用,确保程序退出时强制发送所有缓存的Span:

func main() {
    log.Printf("Waiting for connection...")

    ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
    defer cancel()

    // 恢复Shutdown调用,确保Span被全部发送
    shutdown := initProvider()
    defer shutdown()

    tracer := otel.Tracer("demo-client-tracer")
    ctx, span := tracer.Start(context.TODO(), "span-name")

    defer span.End()
    for i := 0; i < 10; i++ {
        _, iSpan := tracer.Start(ctx, fmt.Sprintf("Sample-%d", i))
        log.Printf("Doing really hard work (%d / 10)\n", i+1)

        <-time.After(time.Second)
        iSpan.End()
    }

    log.Printf("Done!")
}

3. 清理冗余代码

删除或注释掉未被调用的initialize函数,避免代码混淆:

// 注释或删除该函数(未被调用且连接端口错误)
// func initialize() {
// 
//     traceExp, err := otlptracehttp.New(
//         context.Background(),
//         otlptracehttp.WithEndpoint("127.0.0.1:8082"),
//         otlptracehttp.WithURLPath("v1/traces"),
//         otlptracehttp.WithInsecure(),
//     )
//     if err != nil {
//         fmt.Println(err)
//     }
// 
//     bsp := sdktrace.NewBatchSpanProcessor(traceExp)
//     tracerProvider := sdktrace.NewTracerProvider(
//         sdktrace.WithSpanProcessor(bsp),
//     )
// 
//     otel.SetTracerProvider(tracerProvider)
// }

验证

修改后重新运行Go程序,BatchSpanProcessor会在程序结束前通过Shutdown方法将所有Span发送到Collector,你应该能在对应的追踪后端(如Jaeger、Zipkin)中看到完整的追踪数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:00:59