package otel import ( "context" "errors" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/jaeger" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" ) // SetupOTelSDK 初始化 OpenTelemetry SDK,配置 Jaeger 作为追踪数据的后端 func SetupOTelSDK(ctx context.Context, serviceName string, jaegerEndpoint string) (shutdown func(context.Context) error, err error) { var shutdownFuncs []func(context.Context) error // 定义关闭函数,用于在程序退出时关闭 OpenTelemetry SDK shutdown = func(ctx context.Context) error { var err error for _, fn := range shutdownFuncs { err = errors.Join(err, fn(ctx)) } shutdownFuncs = nil return err } // 处理错误,如果发生错误,调用关闭函数并返回错误 handleErr := func(inErr error) { err = errors.Join(inErr, shutdown(ctx)) } // 创建 Jaeger Exporter,用于将追踪数据发送到 Jaeger 后端 exporter, err := jaeger.New( jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(jaegerEndpoint)), // 指定 Jaeger 的 Collector Endpoint ) if err != nil { handleErr(err) return } shutdownFuncs = append(shutdownFuncs, exporter.Shutdown) // 创建 TracerProvider,配置 Jaeger Exporter 和服务资源信息 tp := trace.NewTracerProvider( trace.WithBatcher(exporter), // 使用 Jaeger Exporter trace.WithResource(resource.NewSchemaless( semconv.ServiceNameKey.String(serviceName), // 设置服务名称 )), ) shutdownFuncs = append(shutdownFuncs, tp.Shutdown) otel.SetTracerProvider(tp) // 设置全局 TracerProvider // 设置全局 TextMapPropagator otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) return }