From 2cf4552960810f6d67ec011d81c2140aac006dd8 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 13 Nov 2025 15:16:08 -0800 Subject: [PATCH 01/19] Fix for issue - #2808: Invalid type WSGIRequest for attribute 'request' value opentelemetry --- CHANGELOG.md | 1 + .../sdk/_logs/_internal/export/__init__.py | 8 +++- .../sdk/_shared_internal/__init__.py | 9 ++++ .../shared_internal/test_batch_processor.py | 47 +++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2155602a2f..bd4ace52629 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- opentelemetry-sdk: Added request filter which fixes invalid type at WSGI request headers and attributes - docs: Added sqlcommenter example ([#4734](https://github.com/open-telemetry/opentelemetry-python/pull/4734)) - build: bump ruff to 0.14.1 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py index ad79f3e687f..f2e4bb786c9 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py @@ -33,7 +33,11 @@ ReadableLogRecord, ReadWriteLogRecord, ) -from opentelemetry.sdk._shared_internal import BatchProcessor, DuplicateFilter +from opentelemetry.sdk._shared_internal import ( + BatchProcessor, + DuplicateFilter, + RequestFilter, +) from opentelemetry.sdk.environment_variables import ( OTEL_BLRP_EXPORT_TIMEOUT, OTEL_BLRP_MAX_EXPORT_BATCH_SIZE, @@ -51,6 +55,8 @@ ) _logger = logging.getLogger(__name__) _logger.addFilter(DuplicateFilter()) +_wsgi_request_logger = logging.getLogger("django.request") +_wsgi_request_logger.addFilter(RequestFilter()) class LogRecordExportResult(enum.Enum): diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/__init__.py index cb617253698..01c41def8a1 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/__init__.py @@ -62,6 +62,13 @@ def filter(self, record): return False +class RequestFilter(logging.Filter): + def filter(self, record: logging.LogRecord) -> bool: + request = getattr(record, "request", None) + record.request = str(request) + return True + + class BatchExportStrategy(enum.Enum): EXPORT_ALL = 0 EXPORT_WHILE_BATCH_EXCEEDS_THRESHOLD = 1 @@ -113,6 +120,8 @@ def __init__( ) self._logger = logging.getLogger(__name__) self._logger.addFilter(DuplicateFilter()) + self._wsgi_request_logger = logging.getLogger("django.request") + self._wsgi_request_logger.addFilter(RequestFilter()) self._exporting = exporting self._shutdown = False diff --git a/opentelemetry-sdk/tests/shared_internal/test_batch_processor.py b/opentelemetry-sdk/tests/shared_internal/test_batch_processor.py index f5ed15110b9..5e41d51f6dc 100644 --- a/opentelemetry-sdk/tests/shared_internal/test_batch_processor.py +++ b/opentelemetry-sdk/tests/shared_internal/test_batch_processor.py @@ -38,6 +38,7 @@ ) from opentelemetry.sdk._shared_internal import ( DuplicateFilter, + RequestFilter, ) from opentelemetry.sdk.trace import ReadableSpan from opentelemetry.sdk.trace.export import BatchSpanProcessor @@ -264,3 +265,49 @@ def test_duplicate_logs_filter_works(self): test_logger.info("message") test_logger.info("message") self.assertEqual(len(cm.output), 1) + + +class TestRequestFilter(unittest.TestCase): + def test_converts_http_request_to_string(self): + class DummyRequest: + def __str__(self): + return "" + + request = DummyRequest() + + record = logging.LogRecord( + name="django.request", + level=logging.ERROR, + pathname=__file__, + lineno=0, + msg="test message", + args=(), + exc_info=None, + ) + record.request = request + + expected_repr = str(request) + + request_filter = RequestFilter() + result = request_filter.filter(record) + + self.assertTrue(result) + self.assertEqual(getattr(record, "request", None), expected_repr) + self.assertIsInstance(getattr(record, "request", None), str) + + def test_handles_missing_request_attribute(self): + record = logging.LogRecord( + name="django.request", + level=logging.INFO, + pathname=__file__, + lineno=0, + msg="no request", + args=(), + exc_info=None, + ) + + request_filter = RequestFilter() + result = request_filter.filter(record) + + self.assertTrue(result) + self.assertEqual(getattr(record, "request", None), "None") From ca8cbebce9b29ff6d13257cf6eed0f13941c2509 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 13 Nov 2025 15:20:36 -0800 Subject: [PATCH 02/19] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd4ace52629..5c28654cd3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - opentelemetry-sdk: Added request filter which fixes invalid type at WSGI request headers and attributes + ([#4808](https://github.com/open-telemetry/opentelemetry-python/pull/4808)) - docs: Added sqlcommenter example ([#4734](https://github.com/open-telemetry/opentelemetry-python/pull/4734)) - build: bump ruff to 0.14.1 From 4ac5d783ad0f6887e0b37b5fa20021754b22cc0c Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 13 Nov 2025 15:34:06 -0800 Subject: [PATCH 03/19] Retrigger CI/CD pipeline From 044a3be7ea64ff919019cacf389ee0f45fe430a0 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Wed, 19 Nov 2025 11:08:13 -0800 Subject: [PATCH 04/19] Move logic to api --- .../src/opentelemetry/attributes/__init__.py | 8 ++-- .../tests/attributes/test_attributes.py | 27 +++++++++++ .../sdk/_logs/_internal/export/__init__.py | 3 -- .../sdk/_shared_internal/__init__.py | 9 ---- .../shared_internal/test_batch_processor.py | 47 ------------------- 5 files changed, 30 insertions(+), 64 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index fc3d494631a..a6c3e7c447f 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -180,11 +180,6 @@ def _clean_extended_attribute_value( # Freeze mutable sequences defensively return tuple(cleaned_seq) - raise TypeError( - f"Invalid type {type(value).__name__} for attribute value. " - f"Expected one of {[valid_type.__name__ for valid_type in _VALID_ANY_VALUE_TYPES]} or a " - "sequence of those types", - ) def _clean_extended_attribute( @@ -279,6 +274,9 @@ def __setitem__(self, key: str, value: types.AnyValue) -> None: return if self._extended_attributes: + # Convert types other than AnyValue to strings before cleaning + if not isinstance(value, _VALID_ANY_VALUE_TYPES): + value = str(value) value = _clean_extended_attribute( key, value, self.max_value_len ) diff --git a/opentelemetry-api/tests/attributes/test_attributes.py b/opentelemetry-api/tests/attributes/test_attributes.py index 8a653387254..4c39de86f39 100644 --- a/opentelemetry-api/tests/attributes/test_attributes.py +++ b/opentelemetry-api/tests/attributes/test_attributes.py @@ -301,3 +301,30 @@ def test_extended_attributes(self): bdict["key"] = "value" clean_extended_attribute_mock.assert_called_once() + + def test_wsgi_request_conversion_to_string(self): + """Test that WSGI request objects are converted to strings before calling _clean_extended_attribute.""" + + class DummyWSGIRequest: + def __str__(self): + return "" + + bdict = BoundedAttributes(extended_attributes=True, immutable=False) + wsgi_request = DummyWSGIRequest() + original_request = wsgi_request # Keep reference to original object + + with unittest.mock.patch( + "opentelemetry.attributes._clean_extended_attribute", + return_value="stringified_request", + ) as clean_extended_attribute_mock: + bdict["request"] = wsgi_request + + # Verify that _clean_extended_attribute was called + clean_extended_attribute_mock.assert_called_once() + + # Verify that the value passed to _clean_extended_attribute is a string, not the original object + call_args = clean_extended_attribute_mock.call_args + passed_value = call_args[0][1] # Second argument is the value + self.assertIsInstance(passed_value, str) + self.assertNotEqual(passed_value, original_request) # Should be stringified, not the original object + self.assertIn("DummyWSGIRequest", passed_value) # String representation includes class name diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py index f2e4bb786c9..a8aeb7cc942 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py @@ -36,7 +36,6 @@ from opentelemetry.sdk._shared_internal import ( BatchProcessor, DuplicateFilter, - RequestFilter, ) from opentelemetry.sdk.environment_variables import ( OTEL_BLRP_EXPORT_TIMEOUT, @@ -55,8 +54,6 @@ ) _logger = logging.getLogger(__name__) _logger.addFilter(DuplicateFilter()) -_wsgi_request_logger = logging.getLogger("django.request") -_wsgi_request_logger.addFilter(RequestFilter()) class LogRecordExportResult(enum.Enum): diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/__init__.py index 01c41def8a1..cb617253698 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/__init__.py @@ -62,13 +62,6 @@ def filter(self, record): return False -class RequestFilter(logging.Filter): - def filter(self, record: logging.LogRecord) -> bool: - request = getattr(record, "request", None) - record.request = str(request) - return True - - class BatchExportStrategy(enum.Enum): EXPORT_ALL = 0 EXPORT_WHILE_BATCH_EXCEEDS_THRESHOLD = 1 @@ -120,8 +113,6 @@ def __init__( ) self._logger = logging.getLogger(__name__) self._logger.addFilter(DuplicateFilter()) - self._wsgi_request_logger = logging.getLogger("django.request") - self._wsgi_request_logger.addFilter(RequestFilter()) self._exporting = exporting self._shutdown = False diff --git a/opentelemetry-sdk/tests/shared_internal/test_batch_processor.py b/opentelemetry-sdk/tests/shared_internal/test_batch_processor.py index 5e41d51f6dc..f5ed15110b9 100644 --- a/opentelemetry-sdk/tests/shared_internal/test_batch_processor.py +++ b/opentelemetry-sdk/tests/shared_internal/test_batch_processor.py @@ -38,7 +38,6 @@ ) from opentelemetry.sdk._shared_internal import ( DuplicateFilter, - RequestFilter, ) from opentelemetry.sdk.trace import ReadableSpan from opentelemetry.sdk.trace.export import BatchSpanProcessor @@ -265,49 +264,3 @@ def test_duplicate_logs_filter_works(self): test_logger.info("message") test_logger.info("message") self.assertEqual(len(cm.output), 1) - - -class TestRequestFilter(unittest.TestCase): - def test_converts_http_request_to_string(self): - class DummyRequest: - def __str__(self): - return "" - - request = DummyRequest() - - record = logging.LogRecord( - name="django.request", - level=logging.ERROR, - pathname=__file__, - lineno=0, - msg="test message", - args=(), - exc_info=None, - ) - record.request = request - - expected_repr = str(request) - - request_filter = RequestFilter() - result = request_filter.filter(record) - - self.assertTrue(result) - self.assertEqual(getattr(record, "request", None), expected_repr) - self.assertIsInstance(getattr(record, "request", None), str) - - def test_handles_missing_request_attribute(self): - record = logging.LogRecord( - name="django.request", - level=logging.INFO, - pathname=__file__, - lineno=0, - msg="no request", - args=(), - exc_info=None, - ) - - request_filter = RequestFilter() - result = request_filter.filter(record) - - self.assertTrue(result) - self.assertEqual(getattr(record, "request", None), "None") From 71554ed552bbf53c45e38fb99dda87ef564cfe24 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Wed, 19 Nov 2025 11:45:27 -0800 Subject: [PATCH 05/19] Fix ruff --- .../src/opentelemetry/attributes/__init__.py | 1 - .../tests/attributes/test_attributes.py | 18 +++++++++++------- .../sdk/_logs/_internal/export/__init__.py | 5 +---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index a6c3e7c447f..1d68fe3b1a6 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -181,7 +181,6 @@ def _clean_extended_attribute_value( return tuple(cleaned_seq) - def _clean_extended_attribute( key: str, value: types.AnyValue, max_len: Optional[int] ) -> types.AnyValue: diff --git a/opentelemetry-api/tests/attributes/test_attributes.py b/opentelemetry-api/tests/attributes/test_attributes.py index 4c39de86f39..5237deb9dbc 100644 --- a/opentelemetry-api/tests/attributes/test_attributes.py +++ b/opentelemetry-api/tests/attributes/test_attributes.py @@ -304,27 +304,31 @@ def test_extended_attributes(self): def test_wsgi_request_conversion_to_string(self): """Test that WSGI request objects are converted to strings before calling _clean_extended_attribute.""" - + class DummyWSGIRequest: def __str__(self): return "" - + bdict = BoundedAttributes(extended_attributes=True, immutable=False) wsgi_request = DummyWSGIRequest() original_request = wsgi_request # Keep reference to original object - + with unittest.mock.patch( "opentelemetry.attributes._clean_extended_attribute", return_value="stringified_request", ) as clean_extended_attribute_mock: bdict["request"] = wsgi_request - + # Verify that _clean_extended_attribute was called clean_extended_attribute_mock.assert_called_once() - + # Verify that the value passed to _clean_extended_attribute is a string, not the original object call_args = clean_extended_attribute_mock.call_args passed_value = call_args[0][1] # Second argument is the value self.assertIsInstance(passed_value, str) - self.assertNotEqual(passed_value, original_request) # Should be stringified, not the original object - self.assertIn("DummyWSGIRequest", passed_value) # String representation includes class name + self.assertNotEqual( + passed_value, original_request + ) # Should be stringified, not the original object + self.assertIn( + "DummyWSGIRequest", passed_value + ) # String representation includes class name diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py index a8aeb7cc942..ad79f3e687f 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/export/__init__.py @@ -33,10 +33,7 @@ ReadableLogRecord, ReadWriteLogRecord, ) -from opentelemetry.sdk._shared_internal import ( - BatchProcessor, - DuplicateFilter, -) +from opentelemetry.sdk._shared_internal import BatchProcessor, DuplicateFilter from opentelemetry.sdk.environment_variables import ( OTEL_BLRP_EXPORT_TIMEOUT, OTEL_BLRP_MAX_EXPORT_BATCH_SIZE, From 692e60e6ebe4c852f94cf0976c9b91042b62a279 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Wed, 19 Nov 2025 12:10:01 -0800 Subject: [PATCH 06/19] Fix lint --- opentelemetry-api/src/opentelemetry/attributes/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index 1d68fe3b1a6..edd34b98e21 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -180,6 +180,7 @@ def _clean_extended_attribute_value( # Freeze mutable sequences defensively return tuple(cleaned_seq) + return value def _clean_extended_attribute( key: str, value: types.AnyValue, max_len: Optional[int] From a4394dd84d42cd33bbdb5d4714d1464c490814e9 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Wed, 19 Nov 2025 12:19:29 -0800 Subject: [PATCH 07/19] Fix ruff --- opentelemetry-api/src/opentelemetry/attributes/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index edd34b98e21..04fec92c136 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -182,6 +182,7 @@ def _clean_extended_attribute_value( return value + def _clean_extended_attribute( key: str, value: types.AnyValue, max_len: Optional[int] ) -> types.AnyValue: From 231765e4b80d16349729f04fbf9389f32ec25133 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 08:35:07 -0800 Subject: [PATCH 08/19] Addressed comments --- .../src/opentelemetry/attributes/__init__.py | 9 ++++++++- .../tests/attributes/test_attributes.py | 15 ++------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index 04fec92c136..35e2225b827 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -180,7 +180,14 @@ def _clean_extended_attribute_value( # Freeze mutable sequences defensively return tuple(cleaned_seq) - return value + try: + return str(value) + except Exception: + raise TypeError( + f"Invalid type {type(value).__name__} for attribute value. " + f"Expected one of {[valid_type.__name__ for valid_type in _VALID_ANY_VALUE_TYPES]} or a " + "sequence of those types", + ) def _clean_extended_attribute( diff --git a/opentelemetry-api/tests/attributes/test_attributes.py b/opentelemetry-api/tests/attributes/test_attributes.py index 5237deb9dbc..69e38d43d0f 100644 --- a/opentelemetry-api/tests/attributes/test_attributes.py +++ b/opentelemetry-api/tests/attributes/test_attributes.py @@ -319,16 +319,5 @@ def __str__(self): ) as clean_extended_attribute_mock: bdict["request"] = wsgi_request - # Verify that _clean_extended_attribute was called - clean_extended_attribute_mock.assert_called_once() - - # Verify that the value passed to _clean_extended_attribute is a string, not the original object - call_args = clean_extended_attribute_mock.call_args - passed_value = call_args[0][1] # Second argument is the value - self.assertIsInstance(passed_value, str) - self.assertNotEqual( - passed_value, original_request - ) # Should be stringified, not the original object - self.assertIn( - "DummyWSGIRequest", passed_value - ) # String representation includes class name + # Verify that the request stored in the bounded dict matches the cleaned value + self.assertEqual(bdict["request"], "stringified_request") From 46e3150c6986518e4ab0b29a70a5bf61dc884a06 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 08:58:54 -0800 Subject: [PATCH 09/19] Fix lint --- opentelemetry-api/src/opentelemetry/attributes/__init__.py | 2 +- opentelemetry-api/tests/attributes/test_attributes.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index 35e2225b827..d4e266d6ea5 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -120,7 +120,7 @@ def _clean_attribute( def _clean_extended_attribute_value( value: types.AnyValue, max_len: Optional[int] -) -> types.AnyValue: +) -> types.AnyValue: # disable=too-many-branches # for primitive types just return the value and eventually shorten the string length if value is None or isinstance(value, _VALID_ATTR_VALUE_TYPES): if max_len is not None and isinstance(value, str): diff --git a/opentelemetry-api/tests/attributes/test_attributes.py b/opentelemetry-api/tests/attributes/test_attributes.py index 69e38d43d0f..b35adc260b8 100644 --- a/opentelemetry-api/tests/attributes/test_attributes.py +++ b/opentelemetry-api/tests/attributes/test_attributes.py @@ -311,12 +311,11 @@ def __str__(self): bdict = BoundedAttributes(extended_attributes=True, immutable=False) wsgi_request = DummyWSGIRequest() - original_request = wsgi_request # Keep reference to original object with unittest.mock.patch( "opentelemetry.attributes._clean_extended_attribute", return_value="stringified_request", - ) as clean_extended_attribute_mock: + ): bdict["request"] = wsgi_request # Verify that the request stored in the bounded dict matches the cleaned value From 7f66522f7952006f1eb1937b7b7ad55563c30c80 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 09:10:01 -0800 Subject: [PATCH 10/19] Fix lint --- opentelemetry-api/src/opentelemetry/attributes/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index d4e266d6ea5..651ea1ee431 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -120,7 +120,7 @@ def _clean_attribute( def _clean_extended_attribute_value( value: types.AnyValue, max_len: Optional[int] -) -> types.AnyValue: # disable=too-many-branches +) -> types.AnyValue: # pylint: disable=too-many-branches # for primitive types just return the value and eventually shorten the string length if value is None or isinstance(value, _VALID_ATTR_VALUE_TYPES): if max_len is not None and isinstance(value, str): From fe3b203dbe53358d5b7decc6fdda0ee0c33e2431 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 09:33:35 -0800 Subject: [PATCH 11/19] Retrigger CI/CD pipeline From 197ebfeb4e5076246b362c1e8689b8839b1221a0 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 09:36:40 -0800 Subject: [PATCH 12/19] Fix lint --- opentelemetry-api/src/opentelemetry/attributes/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index 651ea1ee431..eafe58adaf8 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -118,9 +118,9 @@ def _clean_attribute( return None -def _clean_extended_attribute_value( +def _clean_extended_attribute_value( # pylint: disable=too-many-branches value: types.AnyValue, max_len: Optional[int] -) -> types.AnyValue: # pylint: disable=too-many-branches +) -> types.AnyValue: # for primitive types just return the value and eventually shorten the string length if value is None or isinstance(value, _VALID_ATTR_VALUE_TYPES): if max_len is not None and isinstance(value, str): From 65fb0f15661b593bb6c02b3faec129affb7c2b67 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 10:00:33 -0800 Subject: [PATCH 13/19] Fix lint --- opentelemetry-api/src/opentelemetry/attributes/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index eafe58adaf8..857bd5c7737 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -118,7 +118,7 @@ def _clean_attribute( return None -def _clean_extended_attribute_value( # pylint: disable=too-many-branches +def _clean_extended_attribute_value( # pylint: disable=too-many-branches value: types.AnyValue, max_len: Optional[int] ) -> types.AnyValue: # for primitive types just return the value and eventually shorten the string length From fc409dd672721d7dd1dba83ea56990fcc54f80ce Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 10:42:07 -0800 Subject: [PATCH 14/19] Retrigger CI/CD pipeline From de3d6263b962eeaccbb7a2c8ce204eb6d49a524b Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 11:13:36 -0800 Subject: [PATCH 15/19] Fix links --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c28654cd3b..afcb2d14608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -- opentelemetry-sdk: Added request filter which fixes invalid type at WSGI request headers and attributes +- opentelemetry-api: Convert objects of any type other than AnyValue which fixes invalid type at WSGI request attributes ([#4808](https://github.com/open-telemetry/opentelemetry-python/pull/4808)) - docs: Added sqlcommenter example ([#4734](https://github.com/open-telemetry/opentelemetry-python/pull/4734)) @@ -1721,7 +1721,7 @@ can cause a deadlock to occur over `logging._lock` in some cases ([#4636](https: - Add reset for the global configuration object, for testing purposes ([#636](https://github.com/open-telemetry/opentelemetry-python/pull/636)) - Add support for programmatic instrumentation - ([#579](https://github.com/open-telemetry/opentelemetry-python/pull/569)) + ([#569](https://github.com/open-telemetry/opentelemetry-python/pull/569)) ### Changed From 6a892cd3c25351a358a28e796dabce1a5b28a33e Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 11:16:27 -0800 Subject: [PATCH 16/19] Fix format --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afcb2d14608..8e0dbfd4d61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -- opentelemetry-api: Convert objects of any type other than AnyValue which fixes invalid type at WSGI request attributes +- `opentelemetry-api`: Convert objects of any type other than AnyValue which fixes invalid type at WSGI request attributes ([#4808](https://github.com/open-telemetry/opentelemetry-python/pull/4808)) - docs: Added sqlcommenter example ([#4734](https://github.com/open-telemetry/opentelemetry-python/pull/4734)) From 3a73bdfc260f1c1f54ad667147740bbdc3e204fd Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 12:35:56 -0800 Subject: [PATCH 17/19] Retrigger CI/CD pipeline From e4ff5883bc854b791996a624c967892fea68dfd2 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 13:06:42 -0800 Subject: [PATCH 18/19] Retrigger CI/CD pipeline From 7aac39e4750a2485f5985cde48dd24ee5cbe7cb0 Mon Sep 17 00:00:00 2001 From: Radhika Gupta Date: Thu, 20 Nov 2025 13:10:43 -0800 Subject: [PATCH 19/19] Retrigger CI/CD pipeline