@@ -20,6 +20,12 @@ import (
2020 "github.com/jpillora/backoff"
2121 "github.com/prometheus/client_golang/prometheus"
2222 "github.com/rs/zerolog"
23+ "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
24+ "go.opentelemetry.io/otel/sdk/resource"
25+ sdktrace "go.opentelemetry.io/otel/sdk/trace"
26+ semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
27+ "go.opentelemetry.io/otel/trace"
28+ "go.opentelemetry.io/otel/trace/noop"
2329 "golang.org/x/sync/errgroup"
2430 "google.golang.org/grpc/grpclog"
2531
@@ -152,13 +158,7 @@ func run(args []string, stdout io.Writer) error {
152158 return fmt .Errorf ("invalid API token" )
153159 }
154160
155- baseCtx , cancel := context .WithCancel (context .Background ())
156- defer cancel ()
157-
158- g , ctx := errgroup .WithContext (baseCtx )
159-
160161 zerolog .TimeFieldFormat = zerolog .TimeFormatUnixMs
161-
162162 zl := zerolog .New (stdout ).With ().Timestamp ().Str ("program" , filepath .Base (args [0 ])).Logger ()
163163
164164 switch {
@@ -176,6 +176,21 @@ func run(args []string, stdout io.Writer) error {
176176 zerolog .SetGlobalLevel (zerolog .ErrorLevel )
177177 }
178178
179+ baseCtx , cancel := context .WithCancel (context .Background ())
180+ defer cancel ()
181+
182+ var tracerProvider trace.TracerProvider = noop .NewTracerProvider ()
183+ if os .Getenv ("OTEL_EXPORTER_OTLP_ENDPOINT" ) != "" || os .Getenv ("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT" ) != "" {
184+ var err error
185+ tracerProvider , err = newTracerProvider (baseCtx )
186+ if err != nil {
187+ zl .Err (err ).Msg ("could not configure tracer provider, disabling tracing functionality" )
188+ tracerProvider = noop .NewTracerProvider ()
189+ }
190+ }
191+
192+ g , ctx := errgroup .WithContext (baseCtx )
193+
179194 g .Go (func () error {
180195 return signalHandler (ctx , zl .With ().Str ("subsystem" , "signal handler" ).Logger ())
181196 })
@@ -299,6 +314,7 @@ func run(args []string, stdout io.Writer) error {
299314 checksUpdater , err := checks .NewUpdater (checks.UpdaterOptions {
300315 Conn : conn ,
301316 Logger : zl .With ().Str ("subsystem" , "updater" ).Logger (),
317+ TracerProvider : tracerProvider ,
302318 Backoff : newConnectionBackoff (),
303319 Publisher : publisher ,
304320 TenantCh : tenantCh ,
@@ -321,6 +337,7 @@ func run(args []string, stdout io.Writer) error {
321337 adhocHandler , err := adhoc .NewHandler (adhoc.HandlerOpts {
322338 Conn : conn ,
323339 Logger : zl .With ().Str ("subsystem" , "adhoc" ).Logger (),
340+ TracerProvider : tracerProvider ,
324341 Backoff : newConnectionBackoff (),
325342 Publisher : publisher ,
326343 TenantCh : tenantCh ,
@@ -439,3 +456,31 @@ func setupGoMemLimit(ratio float64) error {
439456
440457 return nil
441458}
459+
460+ // newTracerProvider creates a TracerProvider configured with the relevant resource attributes, configured to export
461+ // traces over OTLP+HTTP to the URL defined in the conventional environment variables.
462+ // Callers should check that either OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_EXPORTER_OTLP_TRACES_ENDPOINT are defined,
463+ // otherwise otel will return a broken tracer.
464+ func newTracerProvider (ctx context.Context ) (* sdktrace.TracerProvider , error ) {
465+ te , err := otlptracehttp .New (ctx )
466+ if err != nil {
467+ return nil , fmt .Errorf ("starting otelhttp trace exporter: %w" , err )
468+ }
469+
470+ res , err := resource .Merge (
471+ resource .Default (),
472+ resource .NewWithAttributes (
473+ semconv .SchemaURL ,
474+ semconv .ServiceName ("synthetic-monitoring-agent" ),
475+ semconv .ServiceVersion (version .Short ()),
476+ ),
477+ )
478+ if err != nil {
479+ return nil , fmt .Errorf ("creating otel resources: %w" , err )
480+ }
481+
482+ return sdktrace .NewTracerProvider (
483+ sdktrace .WithBatcher (te ),
484+ sdktrace .WithResource (res ),
485+ ), nil
486+ }
0 commit comments