123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- // Copyright The OpenTelemetry Authors
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package global
- import (
- "sync"
- "sync/atomic"
- "go.opentelemetry.io/otel/propagation"
- "go.opentelemetry.io/otel/trace"
- )
- type (
- tracerProviderHolder struct {
- tp trace.TracerProvider
- }
- propagatorsHolder struct {
- tm propagation.TextMapPropagator
- }
- )
- var (
- globalTracer = defaultTracerValue()
- globalPropagators = defaultPropagatorsValue()
- delegateTraceOnce sync.Once
- delegateTextMapPropagatorOnce sync.Once
- )
- // TracerProvider is the internal implementation for global.TracerProvider.
- func TracerProvider() trace.TracerProvider {
- return globalTracer.Load().(tracerProviderHolder).tp
- }
- // SetTracerProvider is the internal implementation for global.SetTracerProvider.
- func SetTracerProvider(tp trace.TracerProvider) {
- delegateTraceOnce.Do(func() {
- current := TracerProvider()
- if current == tp {
- // Setting the provider to the prior default is nonsense, panic.
- // Panic is acceptable because we are likely still early in the
- // process lifetime.
- panic("invalid TracerProvider, the global instance cannot be reinstalled")
- } else if def, ok := current.(*tracerProvider); ok {
- def.setDelegate(tp)
- }
- })
- globalTracer.Store(tracerProviderHolder{tp: tp})
- }
- // TextMapPropagator is the internal implementation for global.TextMapPropagator.
- func TextMapPropagator() propagation.TextMapPropagator {
- return globalPropagators.Load().(propagatorsHolder).tm
- }
- // SetTextMapPropagator is the internal implementation for global.SetTextMapPropagator.
- func SetTextMapPropagator(p propagation.TextMapPropagator) {
- // For the textMapPropagator already returned by TextMapPropagator
- // delegate to p.
- delegateTextMapPropagatorOnce.Do(func() {
- if current := TextMapPropagator(); current == p {
- // Setting the provider to the prior default is nonsense, panic.
- // Panic is acceptable because we are likely still early in the
- // process lifetime.
- panic("invalid TextMapPropagator, the global instance cannot be reinstalled")
- } else if def, ok := current.(*textMapPropagator); ok {
- def.SetDelegate(p)
- }
- })
- // Return p when subsequent calls to TextMapPropagator are made.
- globalPropagators.Store(propagatorsHolder{tm: p})
- }
- func defaultTracerValue() *atomic.Value {
- v := &atomic.Value{}
- v.Store(tracerProviderHolder{tp: &tracerProvider{}})
- return v
- }
- func defaultPropagatorsValue() *atomic.Value {
- v := &atomic.Value{}
- v.Store(propagatorsHolder{tm: newTextMapPropagator()})
- return v
- }
- // ResetForTest restores the initial global state, for testing purposes.
- func ResetForTest() {
- globalTracer = defaultTracerValue()
- globalPropagators = defaultPropagatorsValue()
- delegateTraceOnce = sync.Once{}
- delegateTextMapPropagatorOnce = sync.Once{}
- }
|