diff --git a/CHANGELOG.md b/CHANGELOG.md index f345d8c2114..32698e94363 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Version 1.25.0/0.46b0 (2024-05-30) +- Fix _encode_events assumes events.attributes.dropped exists + ([#3965](https://github.com/open-telemetry/opentelemetry-python/pull/3965)) - Fix class BoundedAttributes to have RLock rather than Lock ([#3859](https://github.com/open-telemetry/opentelemetry-python/pull/3859)) - Remove thread lock by loading RuntimeContext explicitly. diff --git a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py index dd3d2fc50b8..97cf608ac8f 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py @@ -142,7 +142,7 @@ def _encode_events( name=event.name, time_unix_nano=event.timestamp, attributes=_encode_attributes(event.attributes), - dropped_attributes_count=event.attributes.dropped, + dropped_attributes_count=event.dropped_attributes, ) pb2_events.append(encoded_event) return pb2_events diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index 46c467fb2a2..83dec3a6dd5 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -149,7 +149,7 @@ def setUp(self): ) type(event_mock).name = PropertyMock(return_value="a") - + type(event_mock).dropped_attributes = PropertyMock(return_value=0) self.span = _Span( "a", context=Mock( diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 4c34b8e9d5a..97fb843f6f3 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -337,6 +337,12 @@ def __init__( def attributes(self) -> types.Attributes: return self._attributes + @property + def dropped_attributes(self) -> int: + if isinstance(self._attributes, BoundedAttributes): + return self._attributes.dropped + return 0 + def _check_span_ended(func): def wrapper(self, *args, **kwargs): diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 2a064be80f1..07db25474f7 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -27,6 +27,7 @@ from unittest.mock import Mock, patch from opentelemetry import trace as trace_api +from opentelemetry.attributes import BoundedAttributes from opentelemetry.context import Context from opentelemetry.sdk import resources, trace from opentelemetry.sdk.environment_variables import ( @@ -635,6 +636,15 @@ def test_events(self): span = trace.ReadableSpan("test", events=events) self.assertEqual(span.events, tuple(events)) + def test_event_dropped_attributes(self): + event1 = trace.Event( + "foo1", BoundedAttributes(0, attributes={"bar1": "baz1"}) + ) + self.assertEqual(event1.dropped_attributes, 1) + + event2 = trace.Event("foo2", {"bar2": "baz2"}) + self.assertEqual(event2.dropped_attributes, 0) + class DummyError(Exception): pass @@ -1837,7 +1847,7 @@ def test_dropped_attributes(self): self.assertEqual(1, span.dropped_links) self.assertEqual(2, span.dropped_attributes) self.assertEqual(3, span.dropped_events) - self.assertEqual(2, span.events[0].attributes.dropped) + self.assertEqual(2, span.events[0].dropped_attributes) self.assertEqual(2, span.links[0].attributes.dropped) def _test_span_limits(