@marcel91200 / caddy Mirror · read-only
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 01:00 UTC

master
go 76 lines 2.26 KB
Raw
1 package tracing
2
3 import (
4 "context"
5 "fmt"
6 "sync"
7
8 sdktrace "go.opentelemetry.io/otel/sdk/trace"
9 "go.uber.org/zap"
10 "go.uber.org/zap/zapcore"
11 )
12
13 // globalTracerProvider stores global tracer provider and is responsible for graceful shutdown when nobody is using it.
14 var globalTracerProvider = &tracerProvider{}
15
16 type tracerProvider struct {
17 mu sync.Mutex
18 tracerProvider *sdktrace.TracerProvider
19 tracerProvidersCounter int
20 }
21
22 // getTracerProvider create or return an existing global TracerProvider.
23 //
24 // buildOpts is only invoked when a new provider must actually be created.
25 // This matters because some options (notably sdktrace.WithBatcher) eagerly
26 // start background goroutines when constructed. Building them unconditionally
27 // and then discarding them on the reuse path would leak a BatchSpanProcessor
28 // goroutine on every config reload.
29 func (t *tracerProvider) getTracerProvider(buildOpts func() ([]sdktrace.TracerProviderOption, error)) (*sdktrace.TracerProvider, error) {
30 t.mu.Lock()
31 defer t.mu.Unlock()
32
33 if t.tracerProvider == nil {
34 opts, err := buildOpts()
35 if err != nil {
36 return nil, err
37 }
38 t.tracerProvider = sdktrace.NewTracerProvider(
39 opts...,
40 )
41 }
42
43 t.tracerProvidersCounter++
44
45 return t.tracerProvider, nil
46 }
47
48 // cleanupTracerProvider gracefully shutdown a TracerProvider
49 func (t *tracerProvider) cleanupTracerProvider(logger *zap.Logger) error {
50 t.mu.Lock()
51 defer t.mu.Unlock()
52
53 if t.tracerProvidersCounter > 0 {
54 t.tracerProvidersCounter--
55 }
56
57 if t.tracerProvidersCounter == 0 {
58 if t.tracerProvider != nil {
59 // tracerProvider.ForceFlush SHOULD be invoked according to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#forceflush
60 if err := t.tracerProvider.ForceFlush(context.Background()); err != nil {
61 if c := logger.Check(zapcore.ErrorLevel, "forcing flush"); c != nil {
62 c.Write(zap.Error(err))
63 }
64 }
65
66 // tracerProvider.Shutdown MUST be invoked according to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#shutdown
67 if err := t.tracerProvider.Shutdown(context.Background()); err != nil {
68 return fmt.Errorf("tracerProvider shutdown error: %w", err)
69 }
70 }
71
72 t.tracerProvider = nil
73 }
74
75 return nil
76 }