summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/tracing/tracerprovider.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/caddyhttp/tracing/tracerprovider.go')
-rw-r--r--modules/caddyhttp/tracing/tracerprovider.go63
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
+}