Skip to content

Commit b3f37b3

Browse files
authored
Merge branch 'main' into log-unencodeable-key
2 parents 3a9d2c1 + 857e7ef commit b3f37b3

File tree

4 files changed

+46
-14
lines changed

4 files changed

+46
-14
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2626
([#3973](https://github.com/open-telemetry/opentelemetry-python/pull/3966))
2727
- Update semantic conventions to version 1.26.0.
2828
([#3964](https://github.com/open-telemetry/opentelemetry-python/pull/3964))
29-
- Use semconv exception attributes for record exceptions in spans
29+
- Use semconv exception attributes for record exceptions in spans
3030
([#3979](https://github.com/open-telemetry/opentelemetry-python/pull/3979))
31+
- Validate links at span creation
32+
([#3991](https://github.com/open-telemetry/opentelemetry-python/pull/3991))
3133

3234
## Version 1.25.0/0.46b0 (2024-05-30)
3335

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
psutil = None
8282

8383
LabelValue = AttributeValue
84-
Attributes = typing.Dict[str, LabelValue]
84+
Attributes = typing.Mapping[str, LabelValue]
8585
logger = logging.getLogger(__name__)
8686

8787
CLOUD_PROVIDER = ResourceAttributes.CLOUD_PROVIDER

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

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -816,25 +816,30 @@ def __init__(
816816
)
817817
self._events.append(event)
818818

819-
if links is None:
820-
self._links = self._new_links()
821-
else:
822-
for link in links:
823-
link._attributes = BoundedAttributes(
824-
self._limits.max_link_attributes,
825-
link.attributes,
826-
max_value_len=self._limits.max_attribute_length,
827-
)
828-
self._links = BoundedList.from_seq(self._limits.max_links, links)
819+
self._links = self._new_links(links)
829820

830821
def __repr__(self):
831822
return f'{type(self).__name__}(name="{self._name}", context={self._context})'
832823

833824
def _new_events(self):
834825
return BoundedList(self._limits.max_events)
835826

836-
def _new_links(self):
837-
return BoundedList(self._limits.max_links)
827+
def _new_links(self, links: Sequence[trace_api.Link]):
828+
if not links:
829+
return BoundedList(self._limits.max_links)
830+
831+
valid_links = []
832+
for link in links:
833+
if link and _is_valid_link(link.context, link.attributes):
834+
# pylint: disable=protected-access
835+
link._attributes = BoundedAttributes(
836+
self._limits.max_link_attributes,
837+
link.attributes,
838+
max_value_len=self._limits.max_attribute_length,
839+
)
840+
valid_links.append(link)
841+
842+
return BoundedList.from_seq(self._limits.max_links, valid_links)
838843

839844
def get_span_context(self):
840845
return self._context

opentelemetry-sdk/tests/trace/test_trace.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,14 +954,29 @@ def test_add_link_with_invalid_span_context(self):
954954
root.add_link(None)
955955
self.assertEqual(len(root.links), 0)
956956

957+
with self.tracer.start_as_current_span(
958+
"root", links=[trace_api.Link(other_context), None]
959+
) as root:
960+
self.assertEqual(len(root.links), 0)
961+
957962
def test_add_link_with_invalid_span_context_with_attributes(self):
958963
invalid_context = trace_api.INVALID_SPAN_CONTEXT
959964

960965
with self.tracer.start_as_current_span("root") as root:
966+
root.add_link(invalid_context)
961967
root.add_link(invalid_context, {"name": "neighbor"})
962968
self.assertEqual(len(root.links), 1)
963969
self.assertEqual(root.links[0].attributes, {"name": "neighbor"})
964970

971+
with self.tracer.start_as_current_span(
972+
"root",
973+
links=[
974+
trace_api.Link(invalid_context, {"name": "neighbor"}),
975+
trace_api.Link(invalid_context),
976+
],
977+
) as root:
978+
self.assertEqual(len(root.links), 1)
979+
965980
def test_add_link_with_invalid_span_context_with_tracestate(self):
966981
invalid_context = trace.SpanContext(
967982
trace_api.INVALID_TRACE_ID,
@@ -972,9 +987,19 @@ def test_add_link_with_invalid_span_context_with_tracestate(self):
972987

973988
with self.tracer.start_as_current_span("root") as root:
974989
root.add_link(invalid_context)
990+
root.add_link(trace_api.INVALID_SPAN_CONTEXT)
975991
self.assertEqual(len(root.links), 1)
976992
self.assertEqual(root.links[0].context.trace_state, "foo=bar")
977993

994+
with self.tracer.start_as_current_span(
995+
"root",
996+
links=[
997+
trace_api.Link(invalid_context),
998+
trace_api.Link(trace_api.INVALID_SPAN_CONTEXT),
999+
],
1000+
) as root:
1001+
self.assertEqual(len(root.links), 1)
1002+
9781003
def test_update_name(self):
9791004
with self.tracer.start_as_current_span("root") as root:
9801005
# name

0 commit comments

Comments
 (0)