diff --git a/CHANGELOG.md b/CHANGELOG.md index cfdc5686b56..55197c957c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Fix use of `link.attributes.dropped`, which may not exist + ([#4119](https://github.com/open-telemetry/opentelemetry-python/pull/4119)) - Running mypy on SDK resources ([#4053](https://github.com/open-telemetry/opentelemetry-python/pull/4053)) - Added py.typed file to top-level module 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 97cf608ac8f..d382159e418 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 @@ -157,7 +157,7 @@ def _encode_links(links: Sequence[Link]) -> Sequence[PB2SPan.Link]: trace_id=_encode_trace_id(link.context.trace_id), span_id=_encode_span_id(link.context.span_id), attributes=_encode_attributes(link.attributes), - dropped_attributes_count=link.attributes.dropped, + dropped_attributes_count=link.dropped_attributes, flags=_span_flags(link.context), ) pb2_links.append(encoded_link) 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 46624df1e67..c71e5fbd57f 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 @@ -171,6 +171,7 @@ def setUp(self): "attributes": BoundedAttributes( attributes={"a": 1, "b": False} ), + "dropped_attributes": 0, "kind": OTLPSpan.SpanKind.SPAN_KIND_INTERNAL, # pylint: disable=no-member } ) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 5de5a240d6f..27400c996f1 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -84,6 +84,7 @@ from deprecated import deprecated from opentelemetry import context as context_api +from opentelemetry.attributes import BoundedAttributes from opentelemetry.context.context import Context from opentelemetry.environment_variables import OTEL_PYTHON_TRACER_PROVIDER from opentelemetry.trace.propagation import ( @@ -149,6 +150,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 + _Links = Optional[Sequence[Link]] diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index d039df51ae4..779093f736f 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -669,6 +669,19 @@ def test_event_dropped_attributes(self): event2 = trace.Event("foo2", {"bar2": "baz2"}) self.assertEqual(event2.dropped_attributes, 0) + def test_link_dropped_attributes(self): + link1 = trace_api.Link( + mock.Mock(spec=trace_api.SpanContext), + BoundedAttributes(0, attributes={"bar1": "baz1"}), + ) + self.assertEqual(link1.dropped_attributes, 1) + + link2 = trace_api.Link( + mock.Mock(spec=trace_api.SpanContext), + {"bar2": "baz2"}, + ) + self.assertEqual(link2.dropped_attributes, 0) + class DummyError(Exception): pass @@ -1897,7 +1910,7 @@ def test_dropped_attributes(self): self.assertEqual(2, span.dropped_attributes) self.assertEqual(3, span.dropped_events) self.assertEqual(2, span.events[0].dropped_attributes) - self.assertEqual(2, span.links[0].attributes.dropped) + self.assertEqual(2, span.links[0].dropped_attributes) def _test_span_limits( self,