Files
dance-lessons-coach/pkg/telemetry/telemetry.go
Gabriel Radureau 52065c9cf3
Some checks failed
CI/CD Pipeline / Build Docker Cache (push) Successful in 10s
CI/CD Pipeline / CI Pipeline (push) Failing after 13s
refactor: convert all DanceLessonsCoach mentions to kebab-case
2026-04-07 19:11:39 +02:00

103 lines
2.7 KiB
Go

// Package telemetry provides OpenTelemetry instrumentation for the dance-lessons-coach application
package telemetry
import (
"context"
"log"
"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.21.0"
"go.opentelemetry.io/otel/trace"
)
// Setup initializes OpenTelemetry tracing with the given configuration
type Setup struct {
ServiceName string
OTLPEndpoint string
Insecure bool
SamplerType string
SamplerRatio float64
Version string
}
// InitializeTracing sets up OpenTelemetry tracing provider
func (s *Setup) InitializeTracing(ctx context.Context) (*sdktrace.TracerProvider, error) {
// Create OTLP gRPC exporter
exporter, err := otlptracegrpc.New(ctx,
otlptracegrpc.WithEndpoint(s.OTLPEndpoint),
otlptracegrpc.WithInsecure(),
)
if err != nil {
return nil, err
}
// Create resource with service name and version
res, err := resource.New(ctx,
resource.WithAttributes(
semconv.ServiceName(s.ServiceName),
semconv.ServiceVersion(s.Version),
),
)
if err != nil {
return nil, err
}
// Create sampler based on configuration
sampler := s.getSampler()
// Create trace provider
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(res),
sdktrace.WithSampler(sampler),
)
// Set global tracer provider and propagator
otel.SetTracerProvider(tp)
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
propagation.TraceContext{},
propagation.Baggage{},
))
return tp, nil
}
// Shutdown performs cleanup of the tracer provider
func Shutdown(ctx context.Context, tp *sdktrace.TracerProvider) error {
if tp == nil {
return nil
}
return tp.Shutdown(ctx)
}
// getSampler returns the appropriate sampler based on configuration
func (s *Setup) getSampler() sdktrace.Sampler {
switch s.SamplerType {
case "always_on":
return sdktrace.AlwaysSample()
case "always_off":
return sdktrace.NeverSample()
case "traceidratio":
return sdktrace.TraceIDRatioBased(s.SamplerRatio)
case "parentbased_always_on":
return sdktrace.ParentBased(sdktrace.AlwaysSample())
case "parentbased_always_off":
return sdktrace.ParentBased(sdktrace.NeverSample())
case "parentbased_traceidratio":
return sdktrace.ParentBased(sdktrace.TraceIDRatioBased(s.SamplerRatio))
default:
log.Printf("Unknown sampler type: %s, defaulting to always_on", s.SamplerType)
return sdktrace.AlwaysSample()
}
}
// GetTracer returns a named tracer from the global provider
// Returns a no-op tracer if OpenTelemetry is not initialized
func GetTracer(name string) trace.Tracer {
return otel.Tracer(name)
}