From a10ef49fac95529788dca74eee2146123c34818e Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 14 Jul 2025 12:50:34 -0700 Subject: [PATCH 1/6] Distinguish Azure AI SDKs in statsbeats, also rely on instr scope name for azure sdks --- .../monitor/opentelemetry/exporter/_constants.py | 3 +++ .../exporter/export/trace/_exporter.py | 16 +++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_constants.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_constants.py index 20b22e91e710..70f4303beba1 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_constants.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_constants.py @@ -194,6 +194,8 @@ class _RP_Names(Enum): # Special constant for azure-sdk opentelemetry instrumentation _AZURE_SDK_OPENTELEMETRY_NAME = "azure-sdk-opentelemetry" _AZURE_SDK_NAMESPACE_NAME = "az.namespace" +# TODO: do we need -opentelemetry suffix? +_AZURE_AI_SDK_NAME = "azure-ai" _BASE = 2 @@ -253,6 +255,7 @@ class _RP_Names(Enum): "openai_v2", "vertexai", # Instrumentations below this line have not been added to statsbeat report yet + _AZURE_AI_SDK_NAME ] _INSTRUMENTATIONS_BIT_MAP = {_INSTRUMENTATIONS_LIST[i]: _BASE**i for i in range(len(_INSTRUMENTATIONS_LIST))} diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py index 00335525d370..494f1bcc8d23 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py @@ -23,6 +23,7 @@ _APPLICATIONINSIGHTS_OPENTELEMETRY_RESOURCE_METRIC_DISABLED, _AZURE_SDK_NAMESPACE_NAME, _AZURE_SDK_OPENTELEMETRY_NAME, + _AZURE_AI_SDK_NAME, _INSTRUMENTATION_SUPPORTING_METRICS_LIST, _SAMPLE_RATE_KEY, _METRIC_ENVELOPE_NAME, @@ -525,13 +526,18 @@ def _convert_span_events_to_envelopes(span: ReadableSpan) -> Sequence[TelemetryI def _check_instrumentation_span(span: ReadableSpan) -> None: - # Special use-case for spans generated from azure-sdk services - # Identified by having az.namespace as a span attribute - if span.attributes and _AZURE_SDK_NAMESPACE_NAME in span.attributes: - _utils.add_instrumentation(_AZURE_SDK_OPENTELEMETRY_NAME) - return if span.instrumentation_scope is None: return + + # Special use-case for spans generated from azure-sdk services + # `azure-` or `azure.` is a prefix + if span.instrumentation_scope.name.startswith("azure"): + # spec-case for Azure AI SDKs - identified by `az.namespace` attribute + if (span.attributes.get(_AZURE_SDK_NAMESPACE_NAME or None) == "Microsoft.CognitiveServices"): + _utils.add_instrumentation(_AZURE_AI_SDK_NAME) + else: + _utils.add_instrumentation(_AZURE_SDK_OPENTELEMETRY_NAME) + return # All instrumentation scope names from OpenTelemetry instrumentations have # `opentelemetry.instrumentation.` as a prefix if span.instrumentation_scope.name.startswith("opentelemetry.instrumentation."): From 0e31ec166953e84ab36dfa2eec9a97e8ae8c6e98 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 14 Jul 2025 21:42:20 -0700 Subject: [PATCH 2/6] Update sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../monitor/opentelemetry/exporter/export/trace/_exporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py index 494f1bcc8d23..08c859d456cd 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py @@ -533,7 +533,7 @@ def _check_instrumentation_span(span: ReadableSpan) -> None: # `azure-` or `azure.` is a prefix if span.instrumentation_scope.name.startswith("azure"): # spec-case for Azure AI SDKs - identified by `az.namespace` attribute - if (span.attributes.get(_AZURE_SDK_NAMESPACE_NAME or None) == "Microsoft.CognitiveServices"): + if (span.attributes.get(_AZURE_SDK_NAMESPACE_NAME) == "Microsoft.CognitiveServices"): _utils.add_instrumentation(_AZURE_AI_SDK_NAME) else: _utils.add_instrumentation(_AZURE_SDK_OPENTELEMETRY_NAME) From 532e97dbfac9e252eda4c2b32257254cc88851c6 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 14 Jul 2025 22:46:47 -0700 Subject: [PATCH 3/6] Add tests --- .../tests/trace/test_trace.py | 92 ++++++++++++++++++- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/trace/test_trace.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/trace/test_trace.py index 8ebe8b221a03..df5dc346467c 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/trace/test_trace.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/trace/test_trace.py @@ -11,7 +11,11 @@ # pylint: disable=import-error from opentelemetry.trace import get_tracer_provider, set_tracer_provider from opentelemetry.sdk import trace, resources +from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import SpanExportResult +from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter +from opentelemetry.sdk.trace.export import SimpleSpanProcessor from opentelemetry.sdk.util.instrumentation import InstrumentationScope from opentelemetry.semconv.attributes.exception_attributes import ( EXCEPTION_ESCAPED, @@ -22,6 +26,9 @@ from opentelemetry.trace import Link, SpanContext, SpanKind from opentelemetry.trace.status import Status, StatusCode +from azure.core.settings import settings +from azure.core.tracing.ext.opentelemetry_span import OpenTelemetrySpan +from azure.core.instrumentation import get_tracer as get_azure_sdk_tracer from azure.monitor.opentelemetry.exporter.export._base import ExportResult from azure.monitor.opentelemetry.exporter.export.trace._exporter import ( AzureMonitorTraceExporter, @@ -31,6 +38,7 @@ from azure.monitor.opentelemetry.exporter._constants import ( _AZURE_SDK_NAMESPACE_NAME, _AZURE_SDK_OPENTELEMETRY_NAME, + _AZURE_AI_SDK_NAME, ) from azure.monitor.opentelemetry.exporter._generated.models import ContextTagKeys from azure.monitor.opentelemetry.exporter._utils import azure_monitor_context @@ -1128,7 +1136,7 @@ def test_span_envelope_server_http(self): "url.path": "/path", "url.query": "query", "server.address": "www.example.org", - "server.port": "80" + "server.port": "80", } envelope = exporter._span_to_envelope(span) self.assertEqual(envelope.data.base_data.url, "https://www.example.org:80/path?query") @@ -1687,8 +1695,86 @@ def test_check_instrumentation_span_not_instrumentation(self): def test_check_instrumentation_span_azure_sdk(self): span = mock.Mock() - span.attributes = {_AZURE_SDK_NAMESPACE_NAME: "Microsoft.EventHub"} - span.instrumentation_scope.name = "__main__" + span.attributes = {} + span.instrumentation_scope.name = "azure.foo.bar.__init__" + with mock.patch("azure.monitor.opentelemetry.exporter._utils.add_instrumentation") as add: _check_instrumentation_span(span) add.assert_called_once_with(_AZURE_SDK_OPENTELEMETRY_NAME) + + @mock.patch("opentelemetry.trace.get_tracer_provider") + def test_check_instrumentation_span_azure_sdk_otel_span(self, mock_get_tracer_provider): + mock_get_tracer_provider.return_value = self.get_tracer_provider() + + with OpenTelemetrySpan() as azure_sdk_span: + with mock.patch("azure.monitor.opentelemetry.exporter._utils.add_instrumentation") as add: + _check_instrumentation_span(azure_sdk_span.span_instance) + add.assert_called_once_with(_AZURE_SDK_OPENTELEMETRY_NAME) + + with mock.patch("azure.monitor.opentelemetry.exporter._utils.add_instrumentation") as add: + azure_sdk_span.add_attribute(_AZURE_SDK_NAMESPACE_NAME, "Microsoft.ServiceBus") + _check_instrumentation_span(azure_sdk_span.span_instance) + add.assert_called_once_with(_AZURE_SDK_OPENTELEMETRY_NAME) + + with mock.patch("azure.monitor.opentelemetry.exporter._utils.add_instrumentation") as add: + azure_sdk_span.add_attribute(_AZURE_SDK_NAMESPACE_NAME, "Microsoft.CognitiveServices") + _check_instrumentation_span(azure_sdk_span.span_instance) + add.assert_called_once_with(_AZURE_AI_SDK_NAME) + + @mock.patch("opentelemetry.trace.get_tracer_provider") + def test_check_instrumentation_span_azure_sdk_span_impl(self, mock_get_tracer_provider): + mock_get_tracer_provider.return_value = self.get_tracer_provider() + + settings.tracing_implementation = "opentelemetry" + try: + azure_sdk_span = settings.tracing_implementation()(name="test") + + with mock.patch("azure.monitor.opentelemetry.exporter._utils.add_instrumentation") as add: + _check_instrumentation_span(azure_sdk_span.span_instance) + add.assert_called_once_with(_AZURE_SDK_OPENTELEMETRY_NAME) + + with mock.patch("azure.monitor.opentelemetry.exporter._utils.add_instrumentation") as add: + azure_sdk_span.add_attribute(_AZURE_SDK_NAMESPACE_NAME, "Microsoft.ServiceBus") + _check_instrumentation_span(azure_sdk_span.span_instance) + add.assert_called_once_with(_AZURE_SDK_OPENTELEMETRY_NAME) + + with mock.patch("azure.monitor.opentelemetry.exporter._utils.add_instrumentation") as add: + azure_sdk_span.add_attribute(_AZURE_SDK_NAMESPACE_NAME, "Microsoft.CognitiveServices") + _check_instrumentation_span(azure_sdk_span.span_instance) + add.assert_called_once_with(_AZURE_AI_SDK_NAME) + + finally: + settings.tracing_implementation = None + + @mock.patch("opentelemetry.trace.get_tracer_provider") + def test_check_instrumentation_span_azure_sdk_get_tracer(self, mock_get_tracer_provider): + mock_get_tracer_provider.return_value = self.get_tracer_provider() + + azure_sdk_tracer = get_azure_sdk_tracer(library_name="azure-foo-bar") + azure_sdk_span = azure_sdk_tracer.start_span(name="test") + + with mock.patch("azure.monitor.opentelemetry.exporter._utils.add_instrumentation") as add: + _check_instrumentation_span(azure_sdk_span) + add.assert_called_once_with(_AZURE_SDK_OPENTELEMETRY_NAME) + + with mock.patch("azure.monitor.opentelemetry.exporter._utils.add_instrumentation") as add: + azure_sdk_span.set_attribute(_AZURE_SDK_NAMESPACE_NAME, "Microsoft.ServiceBus") + _check_instrumentation_span(azure_sdk_span) + add.assert_called_once_with(_AZURE_SDK_OPENTELEMETRY_NAME) + + with mock.patch("azure.monitor.opentelemetry.exporter._utils.add_instrumentation") as add: + azure_sdk_span.set_attribute(_AZURE_SDK_NAMESPACE_NAME, "Microsoft.CognitiveServices") + _check_instrumentation_span(azure_sdk_span) + add.assert_called_once_with(_AZURE_AI_SDK_NAME) + + not_azure_sdk_span = get_azure_sdk_tracer(library_name="not-azure-foo-bar").start_span(name="test") + with mock.patch("azure.monitor.opentelemetry.exporter._utils.add_instrumentation") as add: + _check_instrumentation_span(not_azure_sdk_span) + add.assert_not_called() + + def get_tracer_provider(self): + tracer_provider = TracerProvider() + span_exporter = InMemorySpanExporter() + processor = SimpleSpanProcessor(span_exporter) + tracer_provider.add_span_processor(processor) + return tracer_provider From 547064147f6f26854a6f5f5fb6e72c202fd83765 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 15 Jul 2025 10:41:36 -0700 Subject: [PATCH 4/6] Update sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py Co-authored-by: Leighton Chen --- .../monitor/opentelemetry/exporter/export/trace/_exporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py index 08c859d456cd..3484b9573b81 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py @@ -533,7 +533,7 @@ def _check_instrumentation_span(span: ReadableSpan) -> None: # `azure-` or `azure.` is a prefix if span.instrumentation_scope.name.startswith("azure"): # spec-case for Azure AI SDKs - identified by `az.namespace` attribute - if (span.attributes.get(_AZURE_SDK_NAMESPACE_NAME) == "Microsoft.CognitiveServices"): + if (span.attributes and span.attributes.get(_AZURE_SDK_NAMESPACE_NAME) == "Microsoft.CognitiveServices"): _utils.add_instrumentation(_AZURE_AI_SDK_NAME) else: _utils.add_instrumentation(_AZURE_SDK_OPENTELEMETRY_NAME) From 62cb032a7ed97cd8d6e0629e8d3189095eabb9f4 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 15 Jul 2025 10:41:51 -0700 Subject: [PATCH 5/6] Update sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_constants.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../azure/monitor/opentelemetry/exporter/_constants.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_constants.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_constants.py index 70f4303beba1..8a2b03d19f77 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_constants.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_constants.py @@ -194,8 +194,7 @@ class _RP_Names(Enum): # Special constant for azure-sdk opentelemetry instrumentation _AZURE_SDK_OPENTELEMETRY_NAME = "azure-sdk-opentelemetry" _AZURE_SDK_NAMESPACE_NAME = "az.namespace" -# TODO: do we need -opentelemetry suffix? -_AZURE_AI_SDK_NAME = "azure-ai" +_AZURE_AI_SDK_NAME = "azure-ai-opentelemetry" _BASE = 2 From 194d05a37c77321159314f4bf00ac9c4ce7bacc0 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 15 Jul 2025 15:08:09 -0700 Subject: [PATCH 6/6] Make quickpulse log processor support emit and on_emit and sole lint fixes --- .../exporter/_quickpulse/_processor.py | 14 ++++++++++++-- .../azure/monitor/opentelemetry/exporter/_utils.py | 1 + .../exporter/export/trace/_exporter.py | 2 +- .../dev_requirements.txt | 1 + .../tests/quickpulse/test_processor.py | 2 +- .../tests/trace/test_trace.py | 10 +++++++++- 6 files changed, 25 insertions(+), 5 deletions(-) diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_quickpulse/_processor.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_quickpulse/_processor.py index 0bcc69ec1375..e25239bdf45c 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_quickpulse/_processor.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_quickpulse/_processor.py @@ -9,12 +9,22 @@ # pylint: disable=protected-access class _QuickpulseLogRecordProcessor(LogRecordProcessor): + def __init__(self): + super().__init__() + self.call_on_emit = hasattr(super(), 'on_emit') - def emit(self, log_data: LogData) -> None: # type: ignore + def on_emit(self, log_data: LogData) -> None: # type: ignore qpm = _QuickpulseManager._instance if qpm: qpm._record_log_record(log_data) - super().emit(log_data) # type: ignore[safe-super] + if self.call_on_emit: + super().on_emit(log_data) # type: ignore[safe-super] + else: + # this method was removed in opentelemetry-sdk and replaced with on_emit + super().emit(log_data) # type: ignore[safe-super,misc] # pylint: disable=no-member + + def emit(self, log_data: LogData) -> None: + self.on_emit(log_data) def shutdown(self): pass diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_utils.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_utils.py index f2570b88120e..6f9d35c51c01 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_utils.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/_utils.py @@ -124,6 +124,7 @@ def _getlocale(): # by continuing to use getdefaultlocale() even though it has been deprecated. # we ignore the deprecation warnings to reduce noise warnings.simplefilter("ignore", category=DeprecationWarning) + # pylint: disable=deprecated-method return locale.getdefaultlocale()[0] except AttributeError: # locale.getlocal() has issues on Windows: https://github.com/python/cpython/issues/82986 diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py index 3484b9573b81..1e5655382554 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/trace/_exporter.py @@ -533,7 +533,7 @@ def _check_instrumentation_span(span: ReadableSpan) -> None: # `azure-` or `azure.` is a prefix if span.instrumentation_scope.name.startswith("azure"): # spec-case for Azure AI SDKs - identified by `az.namespace` attribute - if (span.attributes and span.attributes.get(_AZURE_SDK_NAMESPACE_NAME) == "Microsoft.CognitiveServices"): + if span.attributes and span.attributes.get(_AZURE_SDK_NAMESPACE_NAME) == "Microsoft.CognitiveServices": _utils.add_instrumentation(_AZURE_AI_SDK_NAME) else: _utils.add_instrumentation(_AZURE_SDK_OPENTELEMETRY_NAME) diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/dev_requirements.txt b/sdk/monitor/azure-monitor-opentelemetry-exporter/dev_requirements.txt index a15b67e9a1d1..3346de096dbe 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/dev_requirements.txt +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/dev_requirements.txt @@ -1,4 +1,5 @@ -e ../../../tools/azure-sdk-tools ../../core/azure-core +../../core/azure-core-tracing-opentelemetry -e ../../identity/azure-identity aiohttp>=3.0; python_version >= '3.7' diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/quickpulse/test_processor.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/quickpulse/test_processor.py index f3948b31e593..98c3a7220b52 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/quickpulse/test_processor.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/quickpulse/test_processor.py @@ -23,7 +23,7 @@ def tearDownClass(cls) -> None: def test_emit(self): processor = _QuickpulseLogRecordProcessor() log_data = mock.Mock() - processor.emit(log_data) + processor.on_emit(log_data) self.qpm._record_log_record.assert_called_once_with(log_data) diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/trace/test_trace.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/trace/test_trace.py index df5dc346467c..4e3885446f91 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/trace/test_trace.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/trace/test_trace.py @@ -28,7 +28,12 @@ from azure.core.settings import settings from azure.core.tracing.ext.opentelemetry_span import OpenTelemetrySpan -from azure.core.instrumentation import get_tracer as get_azure_sdk_tracer + +try: + from azure.core.instrumentation import get_tracer as get_azure_sdk_tracer +except ImportError: + # azure.core.instrumentation is not available in older versions of azure-core + get_azure_sdk_tracer = None from azure.monitor.opentelemetry.exporter.export._base import ExportResult from azure.monitor.opentelemetry.exporter.export.trace._exporter import ( AzureMonitorTraceExporter, @@ -1750,6 +1755,9 @@ def test_check_instrumentation_span_azure_sdk_span_impl(self, mock_get_tracer_pr def test_check_instrumentation_span_azure_sdk_get_tracer(self, mock_get_tracer_provider): mock_get_tracer_provider.return_value = self.get_tracer_provider() + if not get_azure_sdk_tracer: + self.skipTest("azure.core.instrumentation is not available") + azure_sdk_tracer = get_azure_sdk_tracer(library_name="azure-foo-bar") azure_sdk_span = azure_sdk_tracer.start_span(name="test")