package telemetry import ( "context" "time" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/propagation" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.26.0" "gitea.nik4nao.com/nik/home-services/ha-gateway/internal/config" ) // Setup initialises OTel trace and metric providers. If cfg.OTELEndpoint is // empty, no-op providers are installed and Setup returns immediately. The // returned shutdown func flushes and closes both exporters. func Setup(ctx context.Context, cfg *config.Config, version string) (shutdown func(context.Context) error, err error) { if cfg.OTELEndpoint == "" { // Local dev — no telemetry. return func(context.Context) error { return nil }, nil } res, err := resource.New(ctx, resource.WithAttributes( semconv.ServiceName("ha-gateway"), semconv.ServiceVersion(version), ), ) if err != nil { return nil, err } // Trace exporter. traceExp, err := otlptracegrpc.New(ctx, otlptracegrpc.WithEndpoint(cfg.OTELEndpoint), otlptracegrpc.WithInsecure(), ) if err != nil { return nil, err } tp := sdktrace.NewTracerProvider( sdktrace.WithBatcher(traceExp), sdktrace.WithResource(res), ) otel.SetTracerProvider(tp) otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator( propagation.TraceContext{}, propagation.Baggage{}, )) // Metric exporter. metricExp, err := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithEndpoint(cfg.OTELEndpoint), otlpmetricgrpc.WithInsecure(), ) if err != nil { _ = tp.Shutdown(ctx) return nil, err } mp := sdkmetric.NewMeterProvider( sdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricExp, sdkmetric.WithInterval(30*time.Second))), sdkmetric.WithResource(res), ) otel.SetMeterProvider(mp) return func(ctx context.Context) error { if err := tp.Shutdown(ctx); err != nil { return err } return mp.Shutdown(ctx) }, nil }