state.go (4543B)
1 // Copyright The OpenTelemetry Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package global // import "go.opentelemetry.io/otel/internal/global" 16 17 import ( 18 "errors" 19 "sync" 20 "sync/atomic" 21 22 "go.opentelemetry.io/otel/metric" 23 "go.opentelemetry.io/otel/propagation" 24 "go.opentelemetry.io/otel/trace" 25 ) 26 27 type ( 28 tracerProviderHolder struct { 29 tp trace.TracerProvider 30 } 31 32 propagatorsHolder struct { 33 tm propagation.TextMapPropagator 34 } 35 36 meterProviderHolder struct { 37 mp metric.MeterProvider 38 } 39 ) 40 41 var ( 42 globalTracer = defaultTracerValue() 43 globalPropagators = defaultPropagatorsValue() 44 globalMeterProvider = defaultMeterProvider() 45 46 delegateTraceOnce sync.Once 47 delegateTextMapPropagatorOnce sync.Once 48 delegateMeterOnce sync.Once 49 ) 50 51 // TracerProvider is the internal implementation for global.TracerProvider. 52 func TracerProvider() trace.TracerProvider { 53 return globalTracer.Load().(tracerProviderHolder).tp 54 } 55 56 // SetTracerProvider is the internal implementation for global.SetTracerProvider. 57 func SetTracerProvider(tp trace.TracerProvider) { 58 current := TracerProvider() 59 60 if _, cOk := current.(*tracerProvider); cOk { 61 if _, tpOk := tp.(*tracerProvider); tpOk && current == tp { 62 // Do not assign the default delegating TracerProvider to delegate 63 // to itself. 64 Error( 65 errors.New("no delegate configured in tracer provider"), 66 "Setting tracer provider to it's current value. No delegate will be configured", 67 ) 68 return 69 } 70 } 71 72 delegateTraceOnce.Do(func() { 73 if def, ok := current.(*tracerProvider); ok { 74 def.setDelegate(tp) 75 } 76 }) 77 globalTracer.Store(tracerProviderHolder{tp: tp}) 78 } 79 80 // TextMapPropagator is the internal implementation for global.TextMapPropagator. 81 func TextMapPropagator() propagation.TextMapPropagator { 82 return globalPropagators.Load().(propagatorsHolder).tm 83 } 84 85 // SetTextMapPropagator is the internal implementation for global.SetTextMapPropagator. 86 func SetTextMapPropagator(p propagation.TextMapPropagator) { 87 current := TextMapPropagator() 88 89 if _, cOk := current.(*textMapPropagator); cOk { 90 if _, pOk := p.(*textMapPropagator); pOk && current == p { 91 // Do not assign the default delegating TextMapPropagator to 92 // delegate to itself. 93 Error( 94 errors.New("no delegate configured in text map propagator"), 95 "Setting text map propagator to it's current value. No delegate will be configured", 96 ) 97 return 98 } 99 } 100 101 // For the textMapPropagator already returned by TextMapPropagator 102 // delegate to p. 103 delegateTextMapPropagatorOnce.Do(func() { 104 if def, ok := current.(*textMapPropagator); ok { 105 def.SetDelegate(p) 106 } 107 }) 108 // Return p when subsequent calls to TextMapPropagator are made. 109 globalPropagators.Store(propagatorsHolder{tm: p}) 110 } 111 112 // MeterProvider is the internal implementation for global.MeterProvider. 113 func MeterProvider() metric.MeterProvider { 114 return globalMeterProvider.Load().(meterProviderHolder).mp 115 } 116 117 // SetMeterProvider is the internal implementation for global.SetMeterProvider. 118 func SetMeterProvider(mp metric.MeterProvider) { 119 current := MeterProvider() 120 if _, cOk := current.(*meterProvider); cOk { 121 if _, mpOk := mp.(*meterProvider); mpOk && current == mp { 122 // Do not assign the default delegating MeterProvider to delegate 123 // to itself. 124 Error( 125 errors.New("no delegate configured in meter provider"), 126 "Setting meter provider to it's current value. No delegate will be configured", 127 ) 128 return 129 } 130 } 131 132 delegateMeterOnce.Do(func() { 133 if def, ok := current.(*meterProvider); ok { 134 def.setDelegate(mp) 135 } 136 }) 137 globalMeterProvider.Store(meterProviderHolder{mp: mp}) 138 } 139 140 func defaultTracerValue() *atomic.Value { 141 v := &atomic.Value{} 142 v.Store(tracerProviderHolder{tp: &tracerProvider{}}) 143 return v 144 } 145 146 func defaultPropagatorsValue() *atomic.Value { 147 v := &atomic.Value{} 148 v.Store(propagatorsHolder{tm: newTextMapPropagator()}) 149 return v 150 } 151 152 func defaultMeterProvider() *atomic.Value { 153 v := &atomic.Value{} 154 v.Store(meterProviderHolder{mp: &meterProvider{}}) 155 return v 156 }