diff options
author | Connor Brewster <cbrewster@hey.com> | 2024-01-21T20·52-0600 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2024-01-23T15·50+0000 |
commit | d0563294121a85ecddbcc44474373b9293c31e7f (patch) | |
tree | 021246b2b903485df2447b80b767cca7600d6757 /tvix/nar-bridge/cmd/nar-bridge-http/otel.go | |
parent | e8061fc6190fdeaadb9d8ebc8d8dba15c9c6f5c4 (diff) |
feat(tvix/store/nar-bridge): Setup OpenTelemetry r/7442
Sets up OpenTelemetry integration for nar-bridge. Right now it will export spans for HTTP server requests and all gRPC client requests. Having the spans available will make performance work significantly easier as it provides a high level overview of where time is being spent. In the future we can add application-specifc metrics and integrate logrus. Change-Id: Ie3860675d7ffc626a95673ba062c3c798d8bb2a7 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10678 Reviewed-by: flokli <flokli@flokli.de> Tested-by: BuildkiteCI Autosubmit: Connor Brewster <cbrewster@hey.com>
Diffstat (limited to 'tvix/nar-bridge/cmd/nar-bridge-http/otel.go')
-rw-r--r-- | tvix/nar-bridge/cmd/nar-bridge-http/otel.go | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/tvix/nar-bridge/cmd/nar-bridge-http/otel.go b/tvix/nar-bridge/cmd/nar-bridge-http/otel.go new file mode 100644 index 000000000000..c446c6ec1a14 --- /dev/null +++ b/tvix/nar-bridge/cmd/nar-bridge-http/otel.go @@ -0,0 +1,87 @@ +package main + +import ( + "context" + "errors" + + "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" + "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/resource" + "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.24.0" +) + +func setupOpenTelemetry(ctx context.Context, serviceName, serviceVersion string) (func(context.Context) error, error) { + var shutdownFuncs []func(context.Context) error + shutdown := func(ctx context.Context) error { + var err error + for _, fn := range shutdownFuncs { + err = errors.Join(err, fn(ctx)) + } + shutdownFuncs = nil + return err + } + + res, err := resource.Merge( + resource.Default(), + resource.NewWithAttributes( + semconv.SchemaURL, + semconv.ServiceName(serviceName), + semconv.ServiceVersion(serviceVersion), + ), + ) + if err != nil { + return nil, errors.Join(err, shutdown(ctx)) + } + + prop := propagation.NewCompositeTextMapPropagator( + propagation.TraceContext{}, + propagation.Baggage{}, + ) + otel.SetTextMapPropagator(prop) + + tracerProvider, err := newTraceProvider(ctx, res) + if err != nil { + return nil, errors.Join(err, shutdown(ctx)) + } + shutdownFuncs = append(shutdownFuncs, tracerProvider.Shutdown) + otel.SetTracerProvider(tracerProvider) + + meterProvider, err := newMeterProvider(ctx, res) + if err != nil { + return nil, errors.Join(err, shutdown(ctx)) + } + shutdownFuncs = append(shutdownFuncs, meterProvider.Shutdown) + otel.SetMeterProvider(meterProvider) + + return shutdown, nil +} + +func newTraceProvider(ctx context.Context, res *resource.Resource) (*trace.TracerProvider, error) { + traceExporter, err := otlptracegrpc.New(ctx) + if err != nil { + return nil, err + } + + traceProvider := trace.NewTracerProvider( + trace.WithBatcher(traceExporter), + trace.WithResource(res), + ) + return traceProvider, nil +} + +func newMeterProvider(ctx context.Context, res *resource.Resource) (*metric.MeterProvider, error) { + metricExporter, err := otlpmetricgrpc.New(ctx) + if err != nil { + return nil, err + } + + meterProvider := metric.NewMeterProvider( + metric.WithResource(res), + metric.WithReader(metric.NewPeriodicReader(metricExporter)), + ) + return meterProvider, nil +} |