1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3 4 package global // import "go.opentelemetry.io/otel/internal/global"
5 6 import (
7 "errors"
8 "sync"
9 "sync/atomic"
10 11 "go.opentelemetry.io/otel/metric"
12 "go.opentelemetry.io/otel/propagation"
13 "go.opentelemetry.io/otel/trace"
14 )
15 16 type (
17 errorHandlerHolder struct {
18 eh ErrorHandler
19 }
20 21 tracerProviderHolder struct {
22 tp trace.TracerProvider
23 }
24 25 propagatorsHolder struct {
26 tm propagation.TextMapPropagator
27 }
28 29 meterProviderHolder struct {
30 mp metric.MeterProvider
31 }
32 )
33 34 var (
35 globalErrorHandler = defaultErrorHandler()
36 globalTracer = defaultTracerValue()
37 globalPropagators = defaultPropagatorsValue()
38 globalMeterProvider = defaultMeterProvider()
39 40 delegateErrorHandlerOnce sync.Once
41 delegateTraceOnce sync.Once
42 delegateTextMapPropagatorOnce sync.Once
43 delegateMeterOnce sync.Once
44 )
45 46 // GetErrorHandler returns the global ErrorHandler instance.
47 //
48 // The default ErrorHandler instance returned will log all errors to STDERR
49 // until an override ErrorHandler is set with SetErrorHandler. All
50 // ErrorHandler returned prior to this will automatically forward errors to
51 // the set instance instead of logging.
52 //
53 // Subsequent calls to SetErrorHandler after the first will not forward errors
54 // to the new ErrorHandler for prior returned instances.
55 func GetErrorHandler() ErrorHandler {
56 return globalErrorHandler.Load().(errorHandlerHolder).eh
57 }
58 59 // SetErrorHandler sets the global ErrorHandler to h.
60 //
61 // The first time this is called all ErrorHandler previously returned from
62 // GetErrorHandler will send errors to h instead of the default logging
63 // ErrorHandler. Subsequent calls will set the global ErrorHandler, but not
64 // delegate errors to h.
65 func SetErrorHandler(h ErrorHandler) {
66 current := GetErrorHandler()
67 68 if _, cOk := current.(*ErrDelegator); cOk {
69 if _, ehOk := h.(*ErrDelegator); ehOk && current == h {
70 // Do not assign to the delegate of the default ErrDelegator to be
71 // itself.
72 Error(
73 errors.New("no ErrorHandler delegate configured"),
74 "ErrorHandler remains its current value.",
75 )
76 return
77 }
78 }
79 80 delegateErrorHandlerOnce.Do(func() {
81 if def, ok := current.(*ErrDelegator); ok {
82 def.setDelegate(h)
83 }
84 })
85 globalErrorHandler.Store(errorHandlerHolder{eh: h})
86 }
87 88 // TracerProvider is the internal implementation for global.TracerProvider.
89 func TracerProvider() trace.TracerProvider {
90 return globalTracer.Load().(tracerProviderHolder).tp
91 }
92 93 // SetTracerProvider is the internal implementation for global.SetTracerProvider.
94 func SetTracerProvider(tp trace.TracerProvider) {
95 current := TracerProvider()
96 97 if _, cOk := current.(*tracerProvider); cOk {
98 if _, tpOk := tp.(*tracerProvider); tpOk && current == tp {
99 // Do not assign the default delegating TracerProvider to delegate
100 // to itself.
101 Error(
102 errors.New("no delegate configured in tracer provider"),
103 "Setting tracer provider to its current value. No delegate will be configured",
104 )
105 return
106 }
107 }
108 109 delegateTraceOnce.Do(func() {
110 if def, ok := current.(*tracerProvider); ok {
111 def.setDelegate(tp)
112 }
113 })
114 globalTracer.Store(tracerProviderHolder{tp: tp})
115 }
116 117 // TextMapPropagator is the internal implementation for global.TextMapPropagator.
118 func TextMapPropagator() propagation.TextMapPropagator {
119 return globalPropagators.Load().(propagatorsHolder).tm
120 }
121 122 // SetTextMapPropagator is the internal implementation for global.SetTextMapPropagator.
123 func SetTextMapPropagator(p propagation.TextMapPropagator) {
124 current := TextMapPropagator()
125 126 if _, cOk := current.(*textMapPropagator); cOk {
127 if _, pOk := p.(*textMapPropagator); pOk && current == p {
128 // Do not assign the default delegating TextMapPropagator to
129 // delegate to itself.
130 Error(
131 errors.New("no delegate configured in text map propagator"),
132 "Setting text map propagator to its current value. No delegate will be configured",
133 )
134 return
135 }
136 }
137 138 // For the textMapPropagator already returned by TextMapPropagator
139 // delegate to p.
140 delegateTextMapPropagatorOnce.Do(func() {
141 if def, ok := current.(*textMapPropagator); ok {
142 def.SetDelegate(p)
143 }
144 })
145 // Return p when subsequent calls to TextMapPropagator are made.
146 globalPropagators.Store(propagatorsHolder{tm: p})
147 }
148 149 // MeterProvider is the internal implementation for global.MeterProvider.
150 func MeterProvider() metric.MeterProvider {
151 return globalMeterProvider.Load().(meterProviderHolder).mp
152 }
153 154 // SetMeterProvider is the internal implementation for global.SetMeterProvider.
155 func SetMeterProvider(mp metric.MeterProvider) {
156 current := MeterProvider()
157 if _, cOk := current.(*meterProvider); cOk {
158 if _, mpOk := mp.(*meterProvider); mpOk && current == mp {
159 // Do not assign the default delegating MeterProvider to delegate
160 // to itself.
161 Error(
162 errors.New("no delegate configured in meter provider"),
163 "Setting meter provider to its current value. No delegate will be configured",
164 )
165 return
166 }
167 }
168 169 delegateMeterOnce.Do(func() {
170 if def, ok := current.(*meterProvider); ok {
171 def.setDelegate(mp)
172 }
173 })
174 globalMeterProvider.Store(meterProviderHolder{mp: mp})
175 }
176 177 func defaultErrorHandler() *atomic.Value {
178 v := &atomic.Value{}
179 v.Store(errorHandlerHolder{eh: &ErrDelegator{}})
180 return v
181 }
182 183 func defaultTracerValue() *atomic.Value {
184 v := &atomic.Value{}
185 v.Store(tracerProviderHolder{tp: &tracerProvider{}})
186 return v
187 }
188 189 func defaultPropagatorsValue() *atomic.Value {
190 v := &atomic.Value{}
191 v.Store(propagatorsHolder{tm: newTextMapPropagator()})
192 return v
193 }
194 195 func defaultMeterProvider() *atomic.Value {
196 v := &atomic.Value{}
197 v.Store(meterProviderHolder{mp: &meterProvider{}})
198 return v
199 }
200