From b108596d967d162cf59142233c039fd9dcfb0626 Mon Sep 17 00:00:00 2001 From: Seth Maxwell Date: Fri, 5 Jun 2020 20:10:07 +0000 Subject: [PATCH] bugfix: Fix for byte type attributes crashing spans (#775) --- opentelemetry-sdk/CHANGELOG.md | 2 ++ .../src/opentelemetry/sdk/trace/__init__.py | 6 ++++++ opentelemetry-sdk/tests/trace/test_trace.py | 16 ++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index 3e54a63b3ba..0e982b6bc14 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -6,6 +6,8 @@ ([#751](https://github.com/open-telemetry/opentelemetry-python/pull/751)) - Rename Measure to ValueRecorder in metrics ([#761](https://github.com/open-telemetry/opentelemetry-python/pull/761)) +- bugfix: byte type attributes are decoded before adding to attributes dict + ([#775](https://github.com/open-telemetry/opentelemetry-python/pull/775)) ## 0.8b0 diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 20c50a849fd..980caed37d3 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -424,6 +424,12 @@ def set_attribute(self, key: str, value: types.AttributeValue) -> None: # Freeze mutable sequences defensively if isinstance(value, MutableSequence): value = tuple(value) + if isinstance(value, bytes): + try: + value = value.decode() + except ValueError: + logger.warning("Byte attribute could not be decoded.") + return with self._lock: self.attributes[key] = value diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 7e6ab49c39a..32348d87d9e 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -487,6 +487,22 @@ def test_invalid_attribute_values(self): self.assertEqual(len(root.attributes), 0) + def test_byte_type_attribute_value(self): + with self.tracer.start_as_current_span("root") as root: + with self.assertLogs(level=WARNING): + root.set_attribute( + "invalid-byte-type-attribute", + b"\xd8\xe1\xb7\xeb\xa8\xe5 \xd2\xb7\xe1", + ) + self.assertFalse( + "invalid-byte-type-attribute" in root.attributes + ) + + root.set_attribute("valid-byte-type-attribute", b"valid byte") + self.assertTrue( + isinstance(root.attributes["valid-byte-type-attribute"], str) + ) + def test_check_attribute_helper(self): # pylint: disable=protected-access self.assertFalse(trace._is_valid_attribute_value([1, 2, 3.4, "ss", 4]))