|
74 | 74 | """
|
75 | 75 |
|
76 | 76 |
|
| 77 | +import os |
77 | 78 | from abc import ABC, abstractmethod
|
78 | 79 | from contextlib import contextmanager
|
79 | 80 | from enum import Enum
|
@@ -220,6 +221,21 @@ def get_tracer(
|
220 | 221 | return _DefaultTracer()
|
221 | 222 |
|
222 | 223 |
|
| 224 | +class ProxyTracerProvider(TracerProvider): |
| 225 | + def get_tracer( |
| 226 | + self, |
| 227 | + instrumenting_module_name: str, |
| 228 | + instrumenting_library_version: str = "", |
| 229 | + ) -> "Tracer": |
| 230 | + if _TRACER_PROVIDER: |
| 231 | + return _TRACER_PROVIDER.get_tracer( |
| 232 | + instrumenting_module_name, instrumenting_library_version |
| 233 | + ) |
| 234 | + return ProxyTracer( |
| 235 | + instrumenting_module_name, instrumenting_library_version |
| 236 | + ) |
| 237 | + |
| 238 | + |
223 | 239 | class Tracer(ABC):
|
224 | 240 | """Handles span creation and in-process context propagation.
|
225 | 241 |
|
@@ -349,6 +365,40 @@ def start_as_current_span(
|
349 | 365 | """
|
350 | 366 |
|
351 | 367 |
|
| 368 | +class ProxyTracer(Tracer): |
| 369 | + # pylint: disable=W0222,signature-differs |
| 370 | + def __init__( |
| 371 | + self, |
| 372 | + instrumenting_module_name: str, |
| 373 | + instrumenting_library_version: str, |
| 374 | + ): |
| 375 | + self._instrumenting_module_name = instrumenting_module_name |
| 376 | + self._instrumenting_library_version = instrumenting_library_version |
| 377 | + self._real_tracer: Optional[Tracer] = None |
| 378 | + self._noop_tracer = _DefaultTracer() |
| 379 | + |
| 380 | + @property |
| 381 | + def _tracer(self) -> Tracer: |
| 382 | + if self._real_tracer: |
| 383 | + return self._real_tracer |
| 384 | + |
| 385 | + if _TRACER_PROVIDER: |
| 386 | + self._real_tracer = _TRACER_PROVIDER.get_tracer( |
| 387 | + self._instrumenting_module_name, |
| 388 | + self._instrumenting_library_version, |
| 389 | + ) |
| 390 | + return self._real_tracer |
| 391 | + return self._noop_tracer |
| 392 | + |
| 393 | + def start_span(self, *args, **kwargs) -> Span: # type: ignore |
| 394 | + return self._tracer.start_span(*args, **kwargs) # type: ignore |
| 395 | + |
| 396 | + def start_as_current_span( # type: ignore |
| 397 | + self, *args, **kwargs |
| 398 | + ) -> Span: |
| 399 | + return self._tracer.start_as_current_span(*args, **kwargs) # type: ignore |
| 400 | + |
| 401 | + |
352 | 402 | class _DefaultTracer(Tracer):
|
353 | 403 | """The default Tracer, used when no Tracer implementation is available.
|
354 | 404 |
|
@@ -387,6 +437,7 @@ def start_as_current_span(
|
387 | 437 |
|
388 | 438 |
|
389 | 439 | _TRACER_PROVIDER = None
|
| 440 | +_PROXY_TRACER_PROVIDER = None |
390 | 441 |
|
391 | 442 |
|
392 | 443 | def get_tracer(
|
@@ -425,9 +476,18 @@ def set_tracer_provider(tracer_provider: TracerProvider) -> None:
|
425 | 476 |
|
426 | 477 | def get_tracer_provider() -> TracerProvider:
|
427 | 478 | """Gets the current global :class:`~.TracerProvider` object."""
|
428 |
| - global _TRACER_PROVIDER # pylint: disable=global-statement |
| 479 | + # pylint: disable=global-statement |
| 480 | + global _TRACER_PROVIDER |
| 481 | + global _PROXY_TRACER_PROVIDER |
429 | 482 |
|
430 | 483 | if _TRACER_PROVIDER is None:
|
| 484 | + # if a global tracer provider has not been set either via code or env |
| 485 | + # vars, return a proxy tracer provider |
| 486 | + if OTEL_PYTHON_TRACER_PROVIDER not in os.environ: |
| 487 | + if not _PROXY_TRACER_PROVIDER: |
| 488 | + _PROXY_TRACER_PROVIDER = ProxyTracerProvider() |
| 489 | + return _PROXY_TRACER_PROVIDER |
| 490 | + |
431 | 491 | _TRACER_PROVIDER = cast( # type: ignore
|
432 | 492 | "TracerProvider",
|
433 | 493 | _load_provider(OTEL_PYTHON_TRACER_PROVIDER, "tracer_provider"),
|
|
0 commit comments