...

Source file src/go.opentelemetry.io/otel/internal/global/state.go

Documentation: go.opentelemetry.io/otel/internal/global

     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  }
   157  

View as plain text