Skip to content

Commit ef7a415

Browse files
authored
Trace SDK does not raise when Span attribute and link limits are exceeded (#1856)
1 parent 2098c56 commit ef7a415

File tree

4 files changed

+40
-18
lines changed

4 files changed

+40
-18
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4444
([#1818](https://github.com/open-telemetry/opentelemetry-python/pull/1818))
4545
- Update transient errors retry timeout and retryable status codes
4646
([#1842](https://github.com/open-telemetry/opentelemetry-python/pull/1842))
47+
- Fix start span behavior when excess links and attributes are included
48+
([#1856](https://github.com/open-telemetry/opentelemetry-python/pull/1856))
4749

4850
### Removed
4951
- Moved `opentelemetry-instrumentation` to contrib repository.

opentelemetry-sdk/src/opentelemetry/sdk/util/__init__.py

+3-8
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,8 @@ def extend(self, seq):
8181
@classmethod
8282
def from_seq(cls, maxlen, seq):
8383
seq = tuple(seq)
84-
if len(seq) > maxlen:
85-
raise ValueError
8684
bounded_list = cls(maxlen)
87-
# pylint: disable=protected-access
88-
bounded_list._dq = deque(seq, maxlen=maxlen)
85+
bounded_list.extend(seq)
8986
return bounded_list
9087

9188

@@ -140,9 +137,7 @@ def __len__(self):
140137
@classmethod
141138
def from_map(cls, maxlen, mapping):
142139
mapping = OrderedDict(mapping)
143-
if len(mapping) > maxlen:
144-
raise ValueError
145140
bounded_dict = cls(maxlen)
146-
# pylint: disable=protected-access
147-
bounded_dict._dict = mapping
141+
for key, value in mapping.items():
142+
bounded_dict[key] = value
148143
return bounded_dict

opentelemetry-sdk/tests/test_util.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ def test_from_seq(self):
6161
self.assertEqual(len(tuple(blist)), list_len)
6262

6363
# sequence too big
64-
with self.assertRaises(ValueError):
65-
BoundedList.from_seq(list_len / 2, self.base)
64+
blist = BoundedList.from_seq(list_len // 2, base_copy)
65+
self.assertEqual(len(blist), list_len // 2)
66+
self.assertEqual(blist.dropped, list_len - (list_len // 2))
6667

6768
def test_append_no_drop(self):
6869
"""Append max capacity elements to the list without dropping elements."""
@@ -167,8 +168,10 @@ def test_from_map(self):
167168
self.assertEqual(len(tuple(bdict)), dic_len)
168169

169170
# map too big
170-
with self.assertRaises(ValueError):
171-
BoundedDict.from_map(dic_len / 2, self.base)
171+
half_len = dic_len // 2
172+
bdict = BoundedDict.from_map(half_len, self.base)
173+
self.assertEqual(len(tuple(bdict)), half_len)
174+
self.assertEqual(bdict.dropped, dic_len - half_len)
172175

173176
def test_bounded_dict(self):
174177
# create empty dict

opentelemetry-sdk/tests/trace/test_trace.py

+28-6
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
from typing import Optional
2222
from unittest import mock
2323

24-
import pytest
25-
2624
from opentelemetry import trace as trace_api
2725
from opentelemetry.context import Context
2826
from opentelemetry.sdk import resources, trace
@@ -538,6 +536,26 @@ def test_disallow_direct_span_creation(self):
538536
# pylint: disable=abstract-class-instantiated
539537
trace.Span("name", mock.Mock(spec=trace_api.SpanContext))
540538

539+
def test_surplus_span_links(self):
540+
# pylint: disable=protected-access
541+
max_links = trace._SPAN_LINK_COUNT_LIMIT
542+
links = [
543+
trace_api.Link(trace_api.SpanContext(0x1, idx, is_remote=False))
544+
for idx in range(0, 16 + max_links)
545+
]
546+
tracer = new_tracer()
547+
with tracer.start_as_current_span("span", links=links) as root:
548+
self.assertEqual(len(root.links), max_links)
549+
550+
def test_surplus_span_attributes(self):
551+
max_attrs = trace.SPAN_ATTRIBUTE_COUNT_LIMIT
552+
attributes = {str(idx): idx for idx in range(0, 16 + max_attrs)}
553+
tracer = new_tracer()
554+
with tracer.start_as_current_span(
555+
"span", attributes=attributes
556+
) as root:
557+
self.assertEqual(len(root.attributes), max_attrs)
558+
541559

542560
class TestSpan(unittest.TestCase):
543561
# pylint: disable=too-many-public-methods
@@ -1303,11 +1321,15 @@ def test_span_environment_limits(self):
13031321
)
13041322
for _ in range(100)
13051323
]
1306-
with pytest.raises(ValueError):
1307-
with tracer.start_as_current_span("root", links=some_links):
1308-
pass
13091324

1310-
with tracer.start_as_current_span("root") as root:
1325+
some_attrs = {
1326+
"init_attribute_{}".format(idx): idx for idx in range(100)
1327+
}
1328+
with tracer.start_as_current_span(
1329+
"root", links=some_links, attributes=some_attrs
1330+
) as root:
1331+
self.assertEqual(len(root.links), 30)
1332+
self.assertEqual(len(root.attributes), 10)
13111333
for idx in range(100):
13121334
root.set_attribute("my_attribute_{}".format(idx), 0)
13131335
root.add_event("my_event_{}".format(idx))

0 commit comments

Comments
 (0)