diff options
Diffstat (limited to 'modules/caddyhttp/tracing/tracerprovider.go')
-rw-r--r-- | modules/caddyhttp/tracing/tracerprovider.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/modules/caddyhttp/tracing/tracerprovider.go b/modules/caddyhttp/tracing/tracerprovider.go new file mode 100644 index 0000000..035425e --- /dev/null +++ b/modules/caddyhttp/tracing/tracerprovider.go @@ -0,0 +1,63 @@ +package tracing + +import ( + "context" + "fmt" + "sync" + + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.uber.org/zap" +) + +// globalTracerProvider stores global tracer provider and is responsible for graceful shutdown when nobody is using it. +var globalTracerProvider = &tracerProvider{} + +type tracerProvider struct { + mu sync.Mutex + tracerProvider *sdktrace.TracerProvider + tracerProvidersCounter int +} + +// getTracerProvider create or return an existing global TracerProvider +func (t *tracerProvider) getTracerProvider(opts ...sdktrace.TracerProviderOption) *sdktrace.TracerProvider { + t.mu.Lock() + defer t.mu.Unlock() + + t.tracerProvidersCounter++ + + if t.tracerProvider == nil { + t.tracerProvider = sdktrace.NewTracerProvider( + opts..., + ) + } + + return t.tracerProvider +} + +// cleanupTracerProvider gracefully shutdown a TracerProvider +func (t *tracerProvider) cleanupTracerProvider(logger *zap.Logger) error { + t.mu.Lock() + defer t.mu.Unlock() + + if t.tracerProvidersCounter > 0 { + t.tracerProvidersCounter-- + } + + if t.tracerProvidersCounter == 0 { + if t.tracerProvider != nil { + // tracerProvider.ForceFlush SHOULD be invoked according to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#forceflush + if err := t.tracerProvider.ForceFlush(context.Background()); err != nil { + logger.Error("forcing flush", zap.Error(err)) + } + + // tracerProvider.Shutdown MUST be invoked according to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#shutdown + if err := t.tracerProvider.Shutdown(context.Background()); err != nil { + return fmt.Errorf("tracerProvider shutdown error: %w", err) + } + } + + t.tracerProvider = nil + } + + return nil +} |