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
相关产品推荐
相关产品推荐

