diff --git a/CHANGELOG.md b/CHANGELOG.md index 1afd81b6ebc..0a22a6c7c7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -- Add max_scale option to Exponential Bucket Histogram Aggregation [#3323](https://github.com/open-telemetry/opentelemetry-python/pull/3323)) -- Use BoundedAttributes instead of raw dict to extract attributes from LogRecord and Support dropped_attributes_count in LogRecord ([#3310](https://github.com/open-telemetry/opentelemetry-python/pull/3310)) +- Add max_scale option to Exponential Bucket Histogram Aggregation + ([#3323](https://github.com/open-telemetry/opentelemetry-python/pull/3323)) +- Use BoundedAttributes instead of raw dict to extract attributes from LogRecord + ([#3310](https://github.com/open-telemetry/opentelemetry-python/pull/3310)) +- Support dropped_attributes_count in LogRecord and exporters + ([#3351](https://github.com/open-telemetry/opentelemetry-python/pull/3351)) - 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 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 7c135d90baf..47c254033bc 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 @@ -47,6 +47,7 @@ def _encode_log(log_data: LogData) -> PB2LogRecord: body=_encode_value(log_data.log_record.body), 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, severity_number=log_data.log_record.severity_number.value, ) 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 1cd86b2833e..1fdb1977bab 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 @@ -39,7 +39,7 @@ from opentelemetry.proto.resource.v1.resource_pb2 import ( Resource as PB2Resource, ) -from opentelemetry.sdk._logs import LogData +from opentelemetry.sdk._logs import LogData, LogLimits from opentelemetry.sdk._logs import LogRecord as SDKLogRecord from opentelemetry.sdk.resources import Resource as SDKResource from opentelemetry.sdk.util.instrumentation import InstrumentationScope @@ -51,6 +51,19 @@ def test_encode(self): sdk_logs, expected_encoding = self.get_test_logs() 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) + self.assertTrue(hasattr(sdk_logs[0].log_record, "dropped_attributes")) + self.assertEqual( + # pylint:disable=no-member + encoded_logs.resource_logs[0] + .scope_logs[0] + .log_records[0] + .dropped_attributes_count, + 2, + ) + @staticmethod def _get_sdk_log_data() -> List[LogData]: log1 = LogData( @@ -251,3 +264,42 @@ def get_test_logs( ) return sdk_logs, pb2_service_request + + @staticmethod + def _get_test_logs_dropped_attributes() -> List[LogData]: + log1 = LogData( + log_record=SDKLogRecord( + timestamp=1644650195189786880, + trace_id=89564621134313219400156819398935297684, + span_id=1312458408527513268, + trace_flags=TraceFlags(0x01), + severity_text="WARN", + severity_number=SeverityNumber.WARN, + body="Do not go gentle into that good night. Rage, rage against the dying of the light", + resource=SDKResource({"first_resource": "value"}), + attributes={"a": 1, "b": "c", "user_id": "B121092"}, + limits=LogLimits(max_attributes=1), + ), + instrumentation_scope=InstrumentationScope( + "first_name", "first_version" + ), + ) + + log2 = LogData( + log_record=SDKLogRecord( + timestamp=1644650249738562048, + trace_id=0, + span_id=0, + trace_flags=TraceFlags.DEFAULT, + severity_text="WARN", + severity_number=SeverityNumber.WARN, + body="Cooper, this is no time for caution!", + resource=SDKResource({"second_resource": "CASE"}), + attributes={}, + ), + instrumentation_scope=InstrumentationScope( + "second_name", "second_version" + ), + ) + + return [log1, log2] diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py index 7410138067c..578ce2c3916 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py @@ -203,6 +203,7 @@ def to_json(self, indent=4) -> str: "attributes": dict(self.attributes) if bool(self.attributes) else None, + "dropped_attributes": self.dropped_attributes, "timestamp": ns_to_iso_str(self.timestamp), "trace_id": f"0x{format_trace_id(self.trace_id)}" if self.trace_id is not None diff --git a/opentelemetry-sdk/tests/logs/test_log_record.py b/opentelemetry-sdk/tests/logs/test_log_record.py index a5993e5833f..1f0bd785a85 100644 --- a/opentelemetry-sdk/tests/logs/test_log_record.py +++ b/opentelemetry-sdk/tests/logs/test_log_record.py @@ -27,6 +27,7 @@ def test_log_record_to_json(self): "severity_number": "None", "severity_text": None, "attributes": None, + "dropped_attributes": 0, "timestamp": "1970-01-01T00:00:00.000000Z", "trace_id": "", "span_id": "",