Files
obsx/tracer.go
2026-03-23 01:16:18 +03:00

68 lines
1.8 KiB
Go

package obsx
import (
"context"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
"go.opentelemetry.io/otel/trace"
)
// TracerConfig configures the OpenTelemetry tracer.
type TracerConfig struct {
ServiceName string
ServiceVersion string
Endpoint string // OTLP gRPC endpoint, e.g. "localhost:4317"
Sampler float64 // sampling ratio, default: 1.0 (sample everything)
}
func (c *TracerConfig) defaults() {
if c.Sampler <= 0 {
c.Sampler = 1.0
}
}
// SetupTracer initializes an OpenTelemetry tracer provider with OTLP gRPC exporter.
// Returns a shutdown function that must be called on application exit.
func SetupTracer(ctx context.Context, cfg TracerConfig) (shutdown func(context.Context) error, err error) {
cfg.defaults()
exporter, err := otlptracegrpc.New(ctx,
otlptracegrpc.WithEndpoint(cfg.Endpoint),
otlptracegrpc.WithInsecure(),
)
if err != nil {
return nil, err
}
attrs := []resource.Option{
resource.WithAttributes(semconv.ServiceName(cfg.ServiceName)),
}
if cfg.ServiceVersion != "" {
attrs = append(attrs, resource.WithAttributes(semconv.ServiceVersion(cfg.ServiceVersion)))
}
res, err := resource.New(ctx, attrs...)
if err != nil {
return nil, err
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(res),
sdktrace.WithSampler(sdktrace.TraceIDRatioBased(cfg.Sampler)),
)
otel.SetTracerProvider(tp)
return tp.Shutdown, nil
}
// StartSpan starts a new span using the global tracer provider.
func StartSpan(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
return otel.Tracer("obsx").Start(ctx, name, opts...)
}