diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md b/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md index 77d608f56827..118baac1dc6a 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/CHANGELOG.md @@ -9,7 +9,8 @@ ### Bugs Fixed ### Other Changes - +- Update maximum size of custom properties +([#44684](https://github.com/Azure/azure-sdk-for-python/pull/44684)) - Declare support for Python 3.13 and 3.14 ([#44550](https://github.com/Azure/azure-sdk-for-python/pull/44550)) 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 2b08bdb53e5a..2432a96841ac 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 @@ -18,7 +18,10 @@ from opentelemetry.util.types import Attributes from azure.core.pipeline.policies import BearerTokenCredentialPolicy -from azure.monitor.opentelemetry.exporter._generated.models import ContextTagKeys, TelemetryItem +from azure.monitor.opentelemetry.exporter._generated.models import ( + ContextTagKeys, + TelemetryItem, +) from azure.monitor.opentelemetry.exporter._version import VERSION as ext_version from azure.monitor.opentelemetry.exporter._constants import ( _AKS_ARM_NAMESPACE_ID, @@ -127,7 +130,10 @@ def _get_sdk_version_prefix(): def _get_sdk_version(): return "{}py{}:otel{}:ext{}".format( - _get_sdk_version_prefix(), platform.python_version(), opentelemetry_version, ext_version + _get_sdk_version_prefix(), + platform.python_version(), + opentelemetry_version, + ext_version, ) @@ -356,6 +362,7 @@ def _is_any_synthetic_source(properties: Optional[Any]) -> bool: # pylint: disable=W0622 def _filter_custom_properties(properties: Attributes, filter=None) -> Dict[str, str]: + max_length = 64 * 1024 truncated_properties: Dict[str, str] = {} if not properties: return truncated_properties @@ -365,10 +372,10 @@ def _filter_custom_properties(properties: Attributes, filter=None) -> Dict[str, if not filter(key, val): continue # Apply truncation rules - # Max key length is 150, value is 8192 + # Max key length is 150, value is 64 * 1024 if not key or len(key) > 150 or val is None: continue - truncated_properties[key] = str(val)[:8192] + truncated_properties[key] = str(val)[:max_length] return truncated_properties diff --git a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/test_utils.py b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/test_utils.py index 4b279b102271..e5b8b205d0ad 100644 --- a/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/test_utils.py +++ b/sdk/monitor/azure-monitor-opentelemetry-exporter/tests/test_utils.py @@ -35,6 +35,24 @@ class TestUtils(unittest.TestCase): def setUp(self): self._valid_instrumentation_key = "1234abcd-5678-4efa-8abc-1234567890ab" + def test_filter_custom_properties_truncates_and_drops_invalid_entries(self): + oversized_value = "v" * 9000 + properties = { + "valid_key": oversized_value, + "k" * 151: "should_be_dropped", + "": "missing_key", + "short": "ok", + "none_value": None, + } + + filtered = _utils._filter_custom_properties(properties) + + self.assertEqual(len(filtered), 2) + self.assertIn("valid_key", filtered) + self.assertEqual(len(filtered["valid_key"]), 9000) + self.assertEqual(filtered["short"], "ok") + self.assertNotIn("k" * 151, filtered) + def test_nanoseconds_to_duration(self): ns_to_duration = _utils.ns_to_duration self.assertEqual(ns_to_duration(0), "0.00:00:00.000") @@ -262,8 +280,14 @@ def test_populate_part_a_fields_aks_with_unknown_service(self): self.assertEqual(tags.get("ai.cloud.roleInstance"), "testPodName") self.assertEqual(tags.get("ai.internal.nodeName"), tags.get("ai.cloud.roleInstance")) - @patch("azure.monitor.opentelemetry.exporter._utils.ns_to_iso_str", return_value=TEST_TIME) - @patch("azure.monitor.opentelemetry.exporter._utils.azure_monitor_context", TEST_AZURE_MONITOR_CONTEXT) + @patch( + "azure.monitor.opentelemetry.exporter._utils.ns_to_iso_str", + return_value=TEST_TIME, + ) + @patch( + "azure.monitor.opentelemetry.exporter._utils.azure_monitor_context", + TEST_AZURE_MONITOR_CONTEXT, + ) def test_create_telemetry_item(self, mock_ns_to_iso_str): result = _utils._create_telemetry_item(TEST_TIMESTAMP) expected_tags = dict(TEST_AZURE_MONITOR_CONTEXT) @@ -277,38 +301,68 @@ def test_create_telemetry_item(self, mock_ns_to_iso_str): # Unknown SDK Version Prefix - @patch("azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", return_value=False) + @patch( + "azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", + return_value=False, + ) @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="") def test_get_sdk_version_prefix(self, mock_system, mock_isdir): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "uum_") - @patch("azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", return_value=False) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Linux") + @patch( + "azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", + return_value=False, + ) + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Linux", + ) def test_get_sdk_version_prefix_linux(self, mock_system, mock_isdir): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "ulm_") - @patch("azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", return_value=False) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Windows") + @patch( + "azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", + return_value=False, + ) + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Windows", + ) def test_get_sdk_version_prefix_windows(self, mock_system, mock_isdir): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "uwm_") - @patch("azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", return_value=True) + @patch( + "azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", + return_value=True, + ) @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="") def test_get_sdk_version_prefix_attach(self, mock_system, mock_isdir): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "uui_") - @patch("azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", return_value=True) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Linux") + @patch( + "azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", + return_value=True, + ) + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Linux", + ) def test_get_sdk_version_prefix_attach_linux(self, mock_system, mock_isdir): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "uli_") - @patch("azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", return_value=True) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Windows") + @patch( + "azure.monitor.opentelemetry.exporter._utils._is_attach_enabled", + return_value=True, + ) + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Windows", + ) def test_get_sdk_version_prefix_attach_windows(self, mock_system, mock_isdir): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "uwi_") @@ -316,7 +370,9 @@ def test_get_sdk_version_prefix_attach_windows(self, mock_system, mock_isdir): # App Service SDK Version Prefix @patch.dict( - "azure.monitor.opentelemetry.exporter._utils.environ", {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, clear=True + "azure.monitor.opentelemetry.exporter._utils.environ", + {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, + clear=True, ) @patch("azure.monitor.opentelemetry.exporter._utils.isdir", return_value=False) @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="") @@ -325,25 +381,37 @@ def test_get_sdk_version_prefix_app_service(self, mock_system, mock_isdir): self.assertEqual(result, "aum_") @patch.dict( - "azure.monitor.opentelemetry.exporter._utils.environ", {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, clear=True + "azure.monitor.opentelemetry.exporter._utils.environ", + {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, + clear=True, ) @patch("azure.monitor.opentelemetry.exporter._utils.isdir", return_value=False) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Linux") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Linux", + ) def test_get_sdk_version_prefix_app_service_linux(self, mock_system, mock_isdir): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "alm_") @patch.dict( - "azure.monitor.opentelemetry.exporter._utils.environ", {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, clear=True + "azure.monitor.opentelemetry.exporter._utils.environ", + {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, + clear=True, ) @patch("azure.monitor.opentelemetry.exporter._utils.isdir", return_value=False) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Windows") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Windows", + ) def test_get_sdk_version_prefix_app_service_windows(self, mock_system, mock_isdir): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "awm_") @patch.dict( - "azure.monitor.opentelemetry.exporter._utils.environ", {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, clear=True + "azure.monitor.opentelemetry.exporter._utils.environ", + {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, + clear=True, ) @patch("azure.monitor.opentelemetry.exporter._utils.isdir", return_value=True) @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="") @@ -352,19 +420,29 @@ def test_get_sdk_version_prefix_app_service_attach(self, mock_system, mock_isdir self.assertEqual(result, "aui_") @patch.dict( - "azure.monitor.opentelemetry.exporter._utils.environ", {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, clear=True + "azure.monitor.opentelemetry.exporter._utils.environ", + {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, + clear=True, ) @patch("azure.monitor.opentelemetry.exporter._utils.isdir", return_value=True) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Linux") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Linux", + ) def test_get_sdk_version_prefix_app_service_linux_attach(self, mock_system, mock_isdir): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "ali_") @patch.dict( - "azure.monitor.opentelemetry.exporter._utils.environ", {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, clear=True + "azure.monitor.opentelemetry.exporter._utils.environ", + {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, + clear=True, ) @patch("azure.monitor.opentelemetry.exporter._utils.isdir", return_value=True) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Windows") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Windows", + ) def test_get_sdk_version_prefix_app_service_windows_attach(self, mock_system, mock_isdir): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "awi_") @@ -392,7 +470,10 @@ def test_get_sdk_version_prefix_function(self, mock_system): }, clear=True, ) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Linux") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Linux", + ) def test_get_sdk_version_prefix_function_linux(self, mock_system): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "flm_") @@ -405,7 +486,10 @@ def test_get_sdk_version_prefix_function_linux(self, mock_system): }, clear=True, ) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Windows") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Windows", + ) def test_get_sdk_version_prefix_function_windows(self, mock_system): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "fwm_") @@ -433,7 +517,10 @@ def test_get_sdk_version_prefix_function_attach(self, mock_system): }, clear=True, ) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Linux") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Linux", + ) def test_get_sdk_version_prefix_function_linux_attach(self, mock_system): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "fli_") @@ -447,7 +534,10 @@ def test_get_sdk_version_prefix_function_linux_attach(self, mock_system): }, clear=True, ) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Windows") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Windows", + ) def test_get_sdk_version_prefix_function_windows_attach(self, mock_system): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "fwi_") @@ -473,7 +563,10 @@ def test_get_sdk_version_prefix_aks(self, mock_system): }, clear=True, ) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Linux") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Linux", + ) def test_get_sdk_version_prefix_aks_linux(self, mock_system): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "klm_") @@ -485,7 +578,10 @@ def test_get_sdk_version_prefix_aks_linux(self, mock_system): }, clear=True, ) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Windows") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Windows", + ) def test_get_sdk_version_prefix_aks_windows(self, mock_system): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "kwm_") @@ -509,7 +605,10 @@ def test_get_sdk_version_prefix_aks_attach(self, mock_system): }, clear=True, ) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Linux") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Linux", + ) def test_get_sdk_version_prefix_aks_linux_attach(self, mock_system): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "kli_") @@ -521,7 +620,10 @@ def test_get_sdk_version_prefix_aks_linux_attach(self, mock_system): }, clear=True, ) - @patch("azure.monitor.opentelemetry.exporter._utils.platform.system", return_value="Windows") + @patch( + "azure.monitor.opentelemetry.exporter._utils.platform.system", + return_value="Windows", + ) def test_get_sdk_version_prefix_aks_windows_attach(self, mock_system): result = _utils._get_sdk_version_prefix() self.assertEqual(result, "kwi_") @@ -532,7 +634,10 @@ def test_get_sdk_version_prefix_aks_windows_attach(self, mock_system): "azure.monitor.opentelemetry.exporter._utils.isdir", return_value=True, ) - @patch.dict("azure.monitor.opentelemetry.exporter._utils.environ", {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}) + @patch.dict( + "azure.monitor.opentelemetry.exporter._utils.environ", + {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, + ) def test_attach_enabled(self, mock_isdir): self.assertEqual(_utils._is_attach_enabled(), True) @@ -540,7 +645,10 @@ def test_attach_enabled(self, mock_isdir): "azure.monitor.opentelemetry.exporter._utils.isdir", return_value=False, ) - @patch.dict("azure.monitor.opentelemetry.exporter._utils.environ", {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}) + @patch.dict( + "azure.monitor.opentelemetry.exporter._utils.environ", + {"WEBSITE_SITE_NAME": TEST_WEBSITE_SITE_NAME}, + ) def test_attach_app_service_disabled(self, mock_isdir): self.assertEqual(_utils._is_attach_enabled(), False) @@ -623,7 +731,10 @@ def test_is_any_synthetic_source_always_on(self): self.assertTrue(_utils._is_any_synthetic_source(properties)) def test_is_any_synthetic_source_both(self): - properties = {"user_agent.synthetic.type": "bot", "http.user_agent": "Azure-Load-Testing/1.0 AlwaysOn"} + properties = { + "user_agent.synthetic.type": "bot", + "http.user_agent": "Azure-Load-Testing/1.0 AlwaysOn", + } self.assertTrue(_utils._is_any_synthetic_source(properties)) def test_is_any_synthetic_source_none(self):