From 37de27a587fd7be443f01ffc2563b79904042165 Mon Sep 17 00:00:00 2001 From: Scott Ernst Date: Tue, 13 Jun 2023 06:58:18 -0600 Subject: [PATCH] LogRecord Resource Serialization Currently, the `LogRecord.to_json` method serializes the resource object using `repr` of its attributes. This differs from how the serialization process is handled in `ReadableSpan.to_json` and `MetricsData.to_json`, which utilize the `Resource.to_json` functionality directly. Using `repr` does not produce a json-parseable output and doesn't follow the same depth of serialization as the other two signal types. Therefore, this change carries over the serialization process from the spans and metrics signal types to the logs type. Fixes #3345 --- CHANGELOG.md | 4 ++- .../sdk/_logs/_internal/__init__.py | 4 +-- .../tests/logs/test_log_record.py | 27 ++++++++++++++++++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6d98b5e974..8b684bd8654 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add unit to view instrument selection criteria ([#3341](https://github.com/open-telemetry/opentelemetry-python/pull/3341)) - Upgrade opentelemetry-proto to 0.20 and regen - [#3355](https://github.com/open-telemetry/opentelemetry-python/pull/3355)) + ([#3355](https://github.com/open-telemetry/opentelemetry-python/pull/3355)) +- LogRecord now JSON serializes resource objects to match ReadableSpan and MetricsData equivalents + ([#3345](https://github.com/open-telemetry/opentelemetry-python/issues/3345)) ## Version 1.18.0/0.39b0 (2023-05-04) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py index 578ce2c3916..9055968a4a5 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py @@ -212,9 +212,9 @@ def to_json(self, indent=4) -> str: if self.span_id is not None else "", "trace_flags": self.trace_flags, - "resource": repr(self.resource.attributes) + "resource": json.loads(self.resource.to_json()) if self.resource - else "", + else None, }, indent=indent, ) diff --git a/opentelemetry-sdk/tests/logs/test_log_record.py b/opentelemetry-sdk/tests/logs/test_log_record.py index 1f0bd785a85..6d5c3da0e20 100644 --- a/opentelemetry-sdk/tests/logs/test_log_record.py +++ b/opentelemetry-sdk/tests/logs/test_log_record.py @@ -17,6 +17,7 @@ from opentelemetry.attributes import BoundedAttributes from opentelemetry.sdk._logs import LogLimits, LogRecord +from opentelemetry.sdk.resources import Resource class TestLogRecord(unittest.TestCase): @@ -32,7 +33,7 @@ def test_log_record_to_json(self): "trace_id": "", "span_id": "", "trace_flags": None, - "resource": "", + "resource": None, }, indent=4, ) @@ -42,6 +43,30 @@ def test_log_record_to_json(self): ).to_json() self.assertEqual(expected, actual) + def test_log_record_to_json_with_resource(self): + """Should JSON serialize/deserialize Resource objects within log records.""" + expected = json.dumps( + { + "body": "a log line", + "severity_number": "None", + "severity_text": None, + "attributes": None, + "timestamp": "1970-01-01T00:00:00.000000Z", + "trace_id": "", + "span_id": "", + "trace_flags": None, + "resource": {"attributes": {"foo": "bar"}, "schema_url": ""}, + }, + indent=4, + ) + + actual = LogRecord( + timestamp=0, + body="a log line", + resource=Resource(attributes={"foo": "bar"}), + ).to_json() + self.assertEqual(expected, actual) + def test_log_record_bounded_attributes(self): attr = {"key": "value"}