package otel import ( "context" "errors" "time" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.32.0" ) func SetupOTEL(ctx context.Context, traceEndpoint string) (shutdown func(context.Context) error, err error) { var shutdownFuncs []func(context.Context) error shutdown = func(ctx context.Context) error { var err error for _, fn := range shutdownFuncs { err = errors.Join(err, fn(ctx)) } shutdownFuncs = nil return err } handlerErr := func(inErr error) { err = errors.Join(inErr, shutdown(ctx)) } prop := newPropagator() otel.SetTextMapPropagator(prop) tracerProvider, err := newTracerProvider(ctx, traceEndpoint) if err != nil { handlerErr(err) return } shutdownFuncs = append(shutdownFuncs, tracerProvider.Shutdown) otel.SetTracerProvider(tracerProvider) return } func newPropagator() propagation.TextMapPropagator { return propagation.NewCompositeTextMapPropagator( propagation.TraceContext{}, propagation.Baggage{}, ) } func newTracerProvider(ctx context.Context, traceEndpoint string) (*trace.TracerProvider, error) { traceExporter, err := otlptracehttp.New(ctx, otlptracehttp.WithEndpoint(traceEndpoint), otlptracehttp.WithInsecure(), ) if err != nil { return nil, err } traceResource, err := resource.New(ctx, resource.WithAttributes( semconv.ServiceNamespaceKey.String("t-juice.club"), semconv.ServiceName("labmon"), )) if err != nil { return nil, err } tracerProvider := trace.NewTracerProvider( trace.WithBatcher(traceExporter, trace.WithBatchTimeout(time.Second)), trace.WithResource(traceResource), ) return tracerProvider, nil }