108
108
)
109
109
from opentelemetry .trace .status import Status , StatusCode
110
110
from opentelemetry .util import types
111
+ from opentelemetry .util ._once import Once
111
112
from opentelemetry .util ._providers import _load_provider
112
113
113
114
logger = getLogger (__name__ )
@@ -452,8 +453,19 @@ def start_as_current_span(
452
453
yield INVALID_SPAN
453
454
454
455
455
- _TRACER_PROVIDER = None
456
- _PROXY_TRACER_PROVIDER = None
456
+ _TRACER_PROVIDER_SET_ONCE = Once ()
457
+ _TRACER_PROVIDER : Optional [TracerProvider ] = None
458
+ _PROXY_TRACER_PROVIDER = ProxyTracerProvider ()
459
+
460
+
461
+ def _reset_globals () -> None :
462
+ """WARNING: only use this for tests."""
463
+ global _TRACER_PROVIDER_SET_ONCE # pylint: disable=global-statement
464
+ global _TRACER_PROVIDER # pylint: disable=global-statement
465
+ global _PROXY_TRACER_PROVIDER # pylint: disable=global-statement
466
+ _TRACER_PROVIDER_SET_ONCE = Once ()
467
+ _TRACER_PROVIDER = None
468
+ _PROXY_TRACER_PROVIDER = ProxyTracerProvider ()
457
469
458
470
459
471
def get_tracer (
@@ -476,40 +488,40 @@ def get_tracer(
476
488
)
477
489
478
490
491
+ def _set_tracer_provider (tracer_provider : TracerProvider , log : bool ) -> None :
492
+ def set_tp () -> None :
493
+ global _TRACER_PROVIDER # pylint: disable=global-statement
494
+ _TRACER_PROVIDER = tracer_provider
495
+
496
+ did_set = _TRACER_PROVIDER_SET_ONCE .do_once (set_tp )
497
+
498
+ if not did_set :
499
+ logger .warning ("Overriding of current TracerProvider is not allowed" )
500
+
501
+
479
502
def set_tracer_provider (tracer_provider : TracerProvider ) -> None :
480
503
"""Sets the current global :class:`~.TracerProvider` object.
481
504
482
505
This can only be done once, a warning will be logged if any furter attempt
483
506
is made.
484
507
"""
485
- global _TRACER_PROVIDER # pylint: disable=global-statement
486
-
487
- if _TRACER_PROVIDER is not None :
488
- logger .warning ("Overriding of current TracerProvider is not allowed" )
489
- return
490
-
491
- _TRACER_PROVIDER = tracer_provider
508
+ _set_tracer_provider (tracer_provider , log = True )
492
509
493
510
494
511
def get_tracer_provider () -> TracerProvider :
495
512
"""Gets the current global :class:`~.TracerProvider` object."""
496
- # pylint: disable=global-statement
497
- global _TRACER_PROVIDER
498
- global _PROXY_TRACER_PROVIDER
499
-
500
513
if _TRACER_PROVIDER is None :
501
514
# if a global tracer provider has not been set either via code or env
502
515
# vars, return a proxy tracer provider
503
516
if OTEL_PYTHON_TRACER_PROVIDER not in os .environ :
504
- if not _PROXY_TRACER_PROVIDER :
505
- _PROXY_TRACER_PROVIDER = ProxyTracerProvider ()
506
517
return _PROXY_TRACER_PROVIDER
507
518
508
- _TRACER_PROVIDER = cast ( # type: ignore
509
- "TracerProvider" ,
510
- _load_provider (OTEL_PYTHON_TRACER_PROVIDER , "tracer_provider" ),
519
+ tracer_provider : TracerProvider = _load_provider (
520
+ OTEL_PYTHON_TRACER_PROVIDER , "tracer_provider"
511
521
)
512
- return _TRACER_PROVIDER
522
+ _set_tracer_provider (tracer_provider , log = False )
523
+ # _TRACER_PROVIDER will have been set by one thread
524
+ return cast ("TracerProvider" , _TRACER_PROVIDER )
513
525
514
526
515
527
@contextmanager # type: ignore
0 commit comments