|
11 | 11 | import aiohttp |
12 | 12 | import requests |
13 | 13 | from google.protobuf.json_format import MessageToDict |
14 | | -from opentelemetry import context as otel_context, trace |
| 14 | +from opentelemetry import context as otel_context, trace, trace as trace_api |
15 | 15 | from opentelemetry._logs import get_logger_provider, set_logger_provider |
16 | 16 | from opentelemetry._logs.severity import SeverityNumber |
17 | 17 | from opentelemetry.exporter.otlp.proto.http import Compression |
18 | 18 | from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter |
19 | 19 | from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter |
| 20 | +from opentelemetry.sdk import trace as trace_sdk |
20 | 21 | from opentelemetry.sdk._logs import ( |
21 | 22 | LoggerProvider, |
22 | 23 | LoggingHandler, |
|
25 | 26 | ) |
26 | 27 | from opentelemetry.sdk._logs.export import BatchLogRecordProcessor |
27 | 28 | from opentelemetry.sdk.resources import SERVICE_NAME, Resource |
28 | | -from opentelemetry.sdk.trace import SpanProcessor, TracerProvider |
| 29 | +from opentelemetry.sdk.trace import SpanProcessor |
29 | 30 | from opentelemetry.sdk.trace.export import BatchSpanProcessor |
30 | 31 | from opentelemetry.trace import Span, Tracer |
31 | 32 | from opentelemetry.util._decorator import _agnosticcontextmanager |
|
45 | 46 | class _DynamicTracer(Tracer): |
46 | 47 | def __init__(self, instrumenting_module_name: str) -> None: |
47 | 48 | self._instrumenting_module_name = instrumenting_module_name |
48 | | - self._tracer_provider = trace.get_tracer_provider() |
| 49 | + self._tracer_provider: trace_api.TracerProvider = trace.get_tracer_provider() |
49 | 50 | self._tracer = trace.get_tracer(instrumenting_module_name) |
50 | 51 |
|
51 | | - def set_provider(self, tracer_provider: TracerProvider) -> None: |
| 52 | + def set_provider(self, tracer_provider: trace_api.TracerProvider) -> None: |
52 | 53 | self._tracer_provider = tracer_provider |
53 | 54 | self._tracer = trace.get_tracer( |
54 | 55 | self._instrumenting_module_name, |
@@ -98,15 +99,15 @@ def force_flush(self, timeout_millis: int = 30000) -> bool: |
98 | 99 |
|
99 | 100 |
|
100 | 101 | def set_tracer_provider( |
101 | | - tracer_provider: TracerProvider, *, metadata: dict[str, AttributeValue] | None = None |
| 102 | + tracer_provider: trace_api.TracerProvider, *, metadata: dict[str, AttributeValue] | None = None |
102 | 103 | ) -> None: |
103 | 104 | """Set the tracer provider for the livekit-agents. |
104 | 105 |
|
105 | 106 | Args: |
106 | 107 | tracer_provider (TracerProvider): The tracer provider to set. |
107 | 108 | metadata (dict[str, AttributeValue] | None, optional): Metadata to set on all spans. Defaults to None. |
108 | 109 | """ |
109 | | - if metadata: |
| 110 | + if metadata and isinstance(tracer_provider, trace_sdk.TracerProvider): |
110 | 111 | tracer_provider.add_span_processor(_MetadataSpanProcessor(metadata)) |
111 | 112 |
|
112 | 113 | tracer.set_provider(tracer_provider) |
@@ -162,22 +163,30 @@ def __call__(self) -> dict[str, str]: |
162 | 163 | } |
163 | 164 | ) |
164 | 165 |
|
165 | | - if not isinstance(tracer._tracer_provider, TracerProvider): |
166 | | - tracer_provider = TracerProvider(resource=resource) |
| 166 | + # Check if a tracer provider is not set and set one up |
| 167 | + # below shows how the ProxyTracerProvider is returned when none have been setup |
| 168 | + # https://github.com/open-telemetry/opentelemetry-python/blob/0018c0030bac9bdce4487fe5fcb3ec6a542ec904/opentelemetry-api/src/opentelemetry/trace/__init__.py#L555 |
| 169 | + tracer_provider: trace_api.TracerProvider |
| 170 | + if isinstance( |
| 171 | + tracer._tracer_provider, (trace_api.ProxyTracerProvider, trace_api.NoOpTracerProvider) |
| 172 | + ): |
| 173 | + tracer_provider = trace_sdk.TracerProvider(resource=resource) |
167 | 174 | set_tracer_provider(tracer_provider) |
168 | 175 | else: |
169 | 176 | # attach the processor to the existing tracer provider |
170 | 177 | tracer_provider = tracer._tracer_provider |
171 | | - tracer_provider.resource.merge(resource) |
| 178 | + if isinstance(tracer_provider, trace_sdk.TracerProvider): |
| 179 | + tracer_provider.resource.merge(resource) |
172 | 180 |
|
173 | 181 | span_exporter = OTLPSpanExporter( |
174 | 182 | endpoint=f"https://{cloud_hostname}/observability/traces/otlp/v0", |
175 | 183 | compression=otlp_compression, |
176 | 184 | session=session, |
177 | 185 | ) |
178 | 186 |
|
179 | | - tracer_provider.add_span_processor(_MetadataSpanProcessor(metadata)) |
180 | | - tracer_provider.add_span_processor(BatchSpanProcessor(span_exporter)) |
| 187 | + if isinstance(tracer_provider, trace_sdk.TracerProvider): |
| 188 | + tracer_provider.add_span_processor(_MetadataSpanProcessor(metadata)) |
| 189 | + tracer_provider.add_span_processor(BatchSpanProcessor(span_exporter)) |
181 | 190 |
|
182 | 191 | logger_provider = get_logger_provider() |
183 | 192 | if not isinstance(logger_provider, LoggerProvider): |
@@ -428,7 +437,7 @@ def _log( |
428 | 437 |
|
429 | 438 |
|
430 | 439 | def _shutdown_telemetry() -> None: |
431 | | - if isinstance(tracer_provider := tracer._tracer_provider, TracerProvider): |
| 440 | + if isinstance(tracer_provider := tracer._tracer_provider, trace_sdk.TracerProvider): |
432 | 441 | logger.debug("shutting down telemetry tracer provider") |
433 | 442 | tracer_provider.force_flush() |
434 | 443 | tracer_provider.shutdown() |
|
0 commit comments