Skip to content

Commit 9d55b7f

Browse files
authored
Fix setting custom TracerProvider bug with no global TracerProvider (#37469)
1 parent 79f436b commit 9d55b7f

File tree

3 files changed

+74
-12
lines changed

3 files changed

+74
-12
lines changed

sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
### Bugs Fixed
1010

11+
- Fix setting custom `TracerProvider` bug
12+
([#37469](https://github.com/Azure/azure-sdk-for-python/pull/37469))
13+
1114
### Other Changes
1215

1316
## 1.0.0b29 (2024-09-10)

sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class AzureMonitorTraceExporter(BaseExporter, SpanExporter):
7272
"""Azure Monitor Trace exporter for OpenTelemetry."""
7373

7474
def __init__(self, **kwargs: Any):
75-
self._tracer_provider = kwargs.pop("tracer_provider", get_tracer_provider())
75+
self._tracer_provider = kwargs.pop("tracer_provider", None)
7676
super().__init__(**kwargs)
7777

7878
def export(self, spans: Sequence[ReadableSpan], **kwargs: Any) -> SpanExportResult: # pylint: disable=unused-argument
@@ -87,7 +87,7 @@ def export(self, spans: Sequence[ReadableSpan], **kwargs: Any) -> SpanExportResu
8787
if spans and self._should_collect_otel_resource_metric():
8888
resource = None
8989
try:
90-
tracer_provider = self._tracer_provider
90+
tracer_provider = self._tracer_provider or get_tracer_provider()
9191
resource = tracer_provider.resource # type: ignore
9292
envelopes.append(self._get_otel_resource_envelope(resource))
9393
except AttributeError as e:

sdk/monitor/azure-monitor-opentelemetry-exporter/tests/trace/test_trace.py

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
22
# Licensed under the MIT License.
33

4-
54
import json
65
import os
76
import platform
@@ -67,14 +66,10 @@ def tearDownClass(cls):
6766
def test_constructor(self):
6867
"""Test the constructor."""
6968
tp = trace.TracerProvider()
70-
set_tracer_provider(tp)
7169
exporter = AzureMonitorTraceExporter(
7270
connection_string="InstrumentationKey=4321abcd-5678-4efa-8abc-1234567890ab",
7371
)
74-
self.assertEqual(
75-
exporter._tracer_provider,
76-
tp,
77-
)
72+
self.assertIsNone(exporter._tracer_provider)
7873
self.assertEqual(
7974
exporter._instrumentation_key,
8075
"4321abcd-5678-4efa-8abc-1234567890ab",
@@ -83,15 +78,13 @@ def test_constructor(self):
8378
def test_constructor_tracer_provider(self):
8479
"""Test the constructor."""
8580
tp = trace.TracerProvider()
86-
tp2 = trace.TracerProvider()
87-
set_tracer_provider(tp)
8881
exporter = AzureMonitorTraceExporter(
8982
connection_string="InstrumentationKey=4321abcd-5678-4efa-8abc-1234567890ab",
90-
tracer_provider=tp2,
83+
tracer_provider=tp,
9184
)
9285
self.assertEqual(
9386
exporter._tracer_provider,
94-
tp2,
87+
tp,
9588
)
9689
self.assertEqual(
9790
exporter._instrumentation_key,
@@ -157,6 +150,72 @@ def test_export_success(self):
157150
self.assertEqual(result, SpanExportResult.SUCCESS)
158151
self.assertEqual(storage_mock.call_count, 1)
159152

153+
def test_export_with_tracer_provider(self):
154+
mock_resource = mock.Mock()
155+
tp = trace.TracerProvider(
156+
resource=mock_resource,
157+
)
158+
exporter = AzureMonitorTraceExporter(
159+
connection_string="InstrumentationKey=4321abcd-5678-4efa-8abc-1234567890ab",
160+
tracer_provider=tp,
161+
)
162+
test_span = trace._Span(
163+
name="test",
164+
context=SpanContext(
165+
trace_id=36873507687745823477771305566750195431,
166+
span_id=12030755672171557338,
167+
is_remote=False,
168+
),
169+
)
170+
test_span.start()
171+
test_span.end()
172+
with mock.patch(
173+
"azure.monitor.opentelemetry.exporter.AzureMonitorTraceExporter._transmit"
174+
) as transmit: # noqa: E501
175+
transmit.return_value = ExportResult.SUCCESS
176+
storage_mock = mock.Mock()
177+
exporter._transmit_from_storage = storage_mock
178+
with mock.patch(
179+
"azure.monitor.opentelemetry.exporter.AzureMonitorTraceExporter._get_otel_resource_envelope"
180+
) as resource_patch: # noqa: E501
181+
result = exporter.export([test_span])
182+
resource_patch.assert_called_once_with(mock_resource)
183+
self.assertEqual(result, SpanExportResult.SUCCESS)
184+
self.assertEqual(storage_mock.call_count, 1)
185+
186+
def test_export_with_tracer_provider_global(self):
187+
mock_resource = mock.Mock()
188+
tp = trace.TracerProvider(
189+
resource=mock_resource,
190+
)
191+
set_tracer_provider(tp)
192+
exporter = AzureMonitorTraceExporter(
193+
connection_string="InstrumentationKey=4321abcd-5678-4efa-8abc-1234567890ab",
194+
)
195+
test_span = trace._Span(
196+
name="test",
197+
context=SpanContext(
198+
trace_id=36873507687745823477771305566750195431,
199+
span_id=12030755672171557338,
200+
is_remote=False,
201+
),
202+
)
203+
test_span.start()
204+
test_span.end()
205+
with mock.patch(
206+
"azure.monitor.opentelemetry.exporter.AzureMonitorTraceExporter._transmit"
207+
) as transmit: # noqa: E501
208+
transmit.return_value = ExportResult.SUCCESS
209+
storage_mock = mock.Mock()
210+
exporter._transmit_from_storage = storage_mock
211+
with mock.patch(
212+
"azure.monitor.opentelemetry.exporter.AzureMonitorTraceExporter._get_otel_resource_envelope"
213+
) as resource_patch: # noqa: E501
214+
result = exporter.export([test_span])
215+
resource_patch.assert_called_once_with(mock_resource)
216+
self.assertEqual(result, SpanExportResult.SUCCESS)
217+
self.assertEqual(storage_mock.call_count, 1)
218+
160219
@mock.patch("azure.monitor.opentelemetry.exporter.export.trace._exporter._logger")
161220
def test_export_exception(self, logger_mock):
162221
test_span = trace._Span(

0 commit comments

Comments
 (0)