From b0ff6dcd80d9308fa9ca68bf07b5c05a43b067d6 Mon Sep 17 00:00:00 2001 From: Lukas Lihotzki Date: Wed, 26 Mar 2025 22:23:21 +0100 Subject: [PATCH] fix(exporter): convert body to str as fallback --- CHANGELOG.md | 2 ++ .../otlp/proto/common/_internal/__init__.py | 6 +++++- .../common/_internal/_log_encoder/__init__.py | 2 +- .../tests/test_log_encoder.py | 15 +++++++++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07d3121668e..c7aad73c15e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4494](https://github.com/open-telemetry/opentelemetry-python/pull/4494)) - Improve CI by cancelling stale runs and setting timeouts ([#4498](https://github.com/open-telemetry/opentelemetry-python/pull/4498)) +- Fix logging of objects which are convertible to strings + ([#4510](https://github.com/open-telemetry/opentelemetry-python/pull/4510)) ## Version 1.31.0/0.52b0 (2025-03-12) diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py index d1793a734ad..510d15eebad 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py @@ -70,7 +70,9 @@ def _encode_resource(resource: Resource) -> PB2Resource: def _encode_value( - value: Any, allow_null: bool = False + value: Any, + allow_null: bool = False, + fallback: Optional[Callable[[Any], Any]] = None, ) -> Optional[PB2AnyValue]: if allow_null is True and value is None: return None @@ -99,6 +101,8 @@ def _encode_value( ] ) ) + elif fallback is not None: + return _encode_value(fallback(value), allow_null) raise Exception(f"Invalid type {type(value)} of value {value}") diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py index 9cd44844d06..7701b8a4d26 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py @@ -55,7 +55,7 @@ def _encode_log(log_data: LogData) -> PB2LogRecord: span_id=span_id, trace_id=trace_id, flags=int(log_data.log_record.trace_flags), - body=_encode_value(body, allow_null=True), + body=_encode_value(body, allow_null=True, fallback=str), severity_text=log_data.log_record.severity_text, attributes=_encode_attributes(log_data.log_record.attributes), dropped_attributes_count=log_data.log_record.dropped_attributes, diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_log_encoder.py b/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_log_encoder.py index 2c4e39eab10..899c39af978 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_log_encoder.py +++ b/exporter/opentelemetry-exporter-otlp-proto-common/tests/test_log_encoder.py @@ -69,6 +69,21 @@ def test_encode_no_body(self): self.assertEqual(encode_logs(sdk_logs), expected_encoding) + def test_encode_stringifiable(self): + class Stringifiable: + def __init__(self, data): + self.data = data + def __str__(self): + return self.data + + sdk_logs, expected_encoding = self.get_test_logs() + for log in sdk_logs: + body = log.log_record.body + if isinstance(body, str): + log.log_record.body = Stringifiable(body) + + self.assertEqual(encode_logs(sdk_logs), expected_encoding) + def test_dropped_attributes_count(self): sdk_logs = self._get_test_logs_dropped_attributes() encoded_logs = encode_logs(sdk_logs)