diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md b/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md index 0c40b701207c..6ffe11a5c155 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md @@ -7,6 +7,8 @@ ### Breaking Changes ### Bugs Fixed +- Suppress internal sdkstats HTTP pipeline logs from appearing in user's logs + ([#45966](https://github.com/Azure/azure-sdk-for-python/pull/45966)) - Kubernetes pod name takes precedence when populating `cloud_RoleInstance` ([#45884](https://github.com/Azure/azure-sdk-for-python/pull/45884)) diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/_base.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/_base.py index 9055c41fc3ce..14354219d503 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/_base.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/azure/monitor/opentelemetry/exporter/export/_base.py @@ -160,9 +160,13 @@ def __init__(self, **kwargs: Any) -> None: config.logging_policy, # Explicitly disabling to avoid infinite loop of Span creation when data is exported # DistributedTracingPolicy(**kwargs), - config.http_logging_policy or HttpLoggingPolicy(**kwargs), ] + # Exclude HttpLoggingPolicy for the sdkstats exporter so its HTTP + # traffic does not appear in the user's logs. + if not self._is_stats_exporter(): + policies.append(config.http_logging_policy or HttpLoggingPolicy(**kwargs)) + self.client: AzureMonitorClient = AzureMonitorClient( host=self._endpoint, connection_timeout=self._timeout, policies=policies, **kwargs ) diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/test_base_exporter.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/test_base_exporter.py index 55e8ec5ad161..33d8634e04da 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/test_base_exporter.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/test_base_exporter.py @@ -310,6 +310,45 @@ def test_constructor_disable_offline_storage_with_storage_directory(self, mock_g self.assertEqual(base._storage_directory, "test/path") mock_get_temp_dir.assert_not_called() + def test_normal_exporter_includes_http_logging_policy(self): + from azure.core.pipeline.policies import HttpLoggingPolicy + + captured_policies = [] + original_init = AzureMonitorClient.__init__ + + def capturing_init(self, *args, **kwargs): + captured_policies.extend(kwargs.get("policies", [])) + original_init(self, *args, **kwargs) + + with mock.patch.object(AzureMonitorClient, "__init__", capturing_init): + BaseExporter( + connection_string="InstrumentationKey=4321abcd-5678-4efa-8abc-1234567890ab", + ) + self.assertTrue( + any(isinstance(p, HttpLoggingPolicy) for p in captured_policies), + "HttpLoggingPolicy should be present in the pipeline for normal exporters", + ) + + def test_statsbeat_exporter_excludes_http_logging_policy(self): + from azure.core.pipeline.policies import HttpLoggingPolicy + + captured_policies = [] + original_init = AzureMonitorClient.__init__ + + def capturing_init(self, *args, **kwargs): + captured_policies.extend(kwargs.get("policies", [])) + original_init(self, *args, **kwargs) + + with mock.patch.object(AzureMonitorClient, "__init__", capturing_init): + AzureMonitorMetricExporter( + is_sdkstats=True, + disable_offline_storage=True, + ) + self.assertFalse( + any(isinstance(p, HttpLoggingPolicy) for p in captured_policies), + "HttpLoggingPolicy must not be present in the pipeline for statsbeat exporters", + ) + # ======================================================================== # STORAGE TESTS # ========================================================================