package otel import ( "context" "os" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "go.uber.org/zap" "google.golang.org/grpc" ) // Initializes an OTLP exporter, and configures the corresponding trace and metric providers. func InitProvider(logger *zap.Logger, serviceName string) (func(), error) { collectorEndpoint := os.Getenv("OTEL_COLLECTOR_ENDPOINT") if collectorEndpoint == "" { logger.Info("skipping trace exporter registration") return nil, nil } ctx := context.Background() res, err := resource.New(ctx, resource.WithAttributes( semconv.ServiceNameKey.String(serviceName), ), ) if err != nil { return nil, err } traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithInsecure(), otlptracegrpc.WithEndpoint(collectorEndpoint), otlptracegrpc.WithDialOption(grpc.WithBlock()), ) if err != nil { return nil, err } bsp := sdktrace.NewBatchSpanProcessor(traceExporter) tracerProvider := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithResource(res), sdktrace.WithSpanProcessor(bsp), ) otel.SetTracerProvider(tracerProvider) otel.SetTextMapPropagator(propagation.TraceContext{}) // Shutdown will flush any remaining spans and shut down the exporter. return func() { err := tracerProvider.Shutdown(ctx) if err != nil { logger.Fatal("error shutting down trace provider", zap.Error(err)) } }, nil }