Skip to content

Commit 187048a

Browse files
authored
Record links with invalid SpanContext (#3917)
1 parent 832e859 commit 187048a

File tree

4 files changed

+34
-3
lines changed

4 files changed

+34
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3838
([#3823] (https://github.com/open-telemetry/opentelemetry-python/pull/3823))
3939
- Add span flags to OTLP spans and links
4040
([#3881](https://github.com/open-telemetry/opentelemetry-python/pull/3881))
41+
- Record links with invalid SpanContext if either attributes or TraceState are not empty
42+
([#3917](https://github.com/open-telemetry/opentelemetry-python/pull/3917/))
4143
- Add OpenTelemetry trove classifiers to PyPI packages
4244
([#3913] (https://github.com/open-telemetry/opentelemetry-python/pull/3913))
4345

opentelemetry-api/src/opentelemetry/trace/span.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ def add_link( # pylint: disable=no-self-use
127127
128128
Adds a single `Link` with the `SpanContext` of the span to link to and,
129129
optionally, attributes passed as arguments. Implementations may ignore
130-
calls with an invalid span context.
130+
calls with an invalid span context if both attributes and TraceState
131+
are empty.
131132
132133
Note: It is preferred to add links at span creation, instead of calling
133134
this method later since samplers can only consider information already

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,12 @@ def wrapper(self, *args, **kwargs):
347347
return wrapper
348348

349349

350+
def _is_valid_link(context: SpanContext, attributes: types.Attributes) -> bool:
351+
return bool(
352+
context and (context.is_valid or (attributes or context.trace_state))
353+
)
354+
355+
350356
class ReadableSpan:
351357
"""Provides read-only access to span attributes.
352358
@@ -867,7 +873,8 @@ def add_link(
867873
context: SpanContext,
868874
attributes: types.Attributes = None,
869875
) -> None:
870-
if context is None or not context.is_valid:
876+
877+
if not _is_valid_link(context, attributes):
871878
return
872879

873880
attributes = BoundedAttributes(

opentelemetry-sdk/tests/trace/test_trace.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -941,9 +941,30 @@ def test_add_link_with_invalid_span_context(self):
941941

942942
with self.tracer.start_as_current_span("root") as root:
943943
root.add_link(other_context)
944-
944+
root.add_link(None)
945945
self.assertEqual(len(root.links), 0)
946946

947+
def test_add_link_with_invalid_span_context_with_attributes(self):
948+
invalid_context = trace_api.INVALID_SPAN_CONTEXT
949+
950+
with self.tracer.start_as_current_span("root") as root:
951+
root.add_link(invalid_context, {"name": "neighbor"})
952+
self.assertEqual(len(root.links), 1)
953+
self.assertEqual(root.links[0].attributes, {"name": "neighbor"})
954+
955+
def test_add_link_with_invalid_span_context_with_tracestate(self):
956+
invalid_context = trace.SpanContext(
957+
trace_api.INVALID_TRACE_ID,
958+
trace_api.INVALID_SPAN_ID,
959+
is_remote=False,
960+
trace_state="foo=bar",
961+
)
962+
963+
with self.tracer.start_as_current_span("root") as root:
964+
root.add_link(invalid_context)
965+
self.assertEqual(len(root.links), 1)
966+
self.assertEqual(root.links[0].context.trace_state, "foo=bar")
967+
947968
def test_update_name(self):
948969
with self.tracer.start_as_current_span("root") as root:
949970
# name

0 commit comments

Comments
 (0)