state.go raw

   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