Skip to content

Commit 5f188f7

Browse files
toumorokoshic24tAlex Boten
authored
sdk: span parents are now always spancontext (#548)
Exporter and span handling complexity was increasing due to the Span.parent attribute being either a Span or a SpanContext. As there is no requirement in the specification to have the parent attribute be a Span, removing this complexity and handling. Co-authored-by: Chris Kleinknecht <[email protected]> Co-authored-by: Alex Boten <[email protected]>
1 parent 216bd5a commit 5f188f7

File tree

11 files changed

+27
-36
lines changed

11 files changed

+27
-36
lines changed

ext/opentelemetry-ext-docker-tests/tests/mysql/test_mysql_functional.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def validate_spans(self):
6565
self.assertEqual(root_span.name, "rootSpan")
6666
self.assertEqual(db_span.name, "mysql.opentelemetry-tests")
6767
self.assertIsNotNone(db_span.parent)
68-
self.assertEqual(db_span.parent.name, root_span.name)
68+
self.assertIs(db_span.parent, root_span.get_context())
6969
self.assertIs(db_span.kind, trace_api.SpanKind.CLIENT)
7070
self.assertEqual(db_span.attributes["db.instance"], MYSQL_DB_NAME)
7171
self.assertEqual(db_span.attributes["net.peer.name"], MYSQL_HOST)

ext/opentelemetry-ext-docker-tests/tests/postgres/test_psycopg_functional.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def validate_spans(self):
6868
self.assertEqual(root_span.name, "rootSpan")
6969
self.assertEqual(child_span.name, "postgresql.opentelemetry-tests")
7070
self.assertIsNotNone(child_span.parent)
71-
self.assertEqual(child_span.parent.name, root_span.name)
71+
self.assertIs(child_span.parent, root_span.get_context())
7272
self.assertIs(child_span.kind, trace_api.SpanKind.CLIENT)
7373
self.assertEqual(
7474
child_span.attributes["db.instance"], POSTGRES_DB_NAME

ext/opentelemetry-ext-docker-tests/tests/pymongo/test_pymongo_functional.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def validate_spans(self):
5151
self.assertIsNot(root_span, None)
5252
self.assertIsNot(pymongo_span, None)
5353
self.assertIsNotNone(pymongo_span.parent)
54-
self.assertEqual(pymongo_span.parent.name, root_span.name)
54+
self.assertIs(pymongo_span.parent, root_span.get_context())
5555
self.assertIs(pymongo_span.kind, trace_api.SpanKind.CLIENT)
5656
self.assertEqual(
5757
pymongo_span.attributes["db.instance"], MONGODB_DB_NAME

ext/opentelemetry-ext-docker-tests/tests/pymysql/test_pymysql_functional.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def validate_spans(self):
7676
self.assertEqual(root_span.name, "rootSpan")
7777
self.assertEqual(db_span.name, "mysql.opentelemetry-tests")
7878
self.assertIsNotNone(db_span.parent)
79-
self.assertEqual(db_span.parent.name, root_span.name)
79+
self.assertIs(db_span.parent, root_span.get_context())
8080
self.assertIs(db_span.kind, trace_api.SpanKind.CLIENT)
8181
self.assertEqual(db_span.attributes["db.instance"], MYSQL_DB_NAME)
8282
self.assertEqual(db_span.attributes["net.peer.name"], MYSQL_HOST)

ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/__init__.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,7 @@ def _translate_to_jaeger(spans: Span):
194194

195195
status = span.status
196196

197-
parent_id = 0
198-
if isinstance(span.parent, trace_api.Span):
199-
parent_id = span.parent.get_context().span_id
200-
elif isinstance(span.parent, trace_api.SpanContext):
201-
parent_id = span.parent.span_id
197+
parent_id = span.parent.span_id if span.parent else 0
202198

203199
tags = _extract_tags(span.attributes)
204200

ext/opentelemetry-ext-opentracing-shim/tests/test_shim.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,8 @@ def test_parent_child_implicit(self):
281281

282282
self.assertEqual(parent_trace_id, child_trace_id)
283283
self.assertEqual(
284-
child.span.unwrap().parent, parent.span.unwrap()
284+
child.span.unwrap().parent,
285+
parent.span.unwrap().get_context(),
285286
)
286287

287288
# Verify parent span becomes the active span again.
@@ -309,7 +310,9 @@ def test_parent_child_explicit_span(self):
309310
child_trace_id = child.span.unwrap().get_context().trace_id
310311

311312
self.assertEqual(child_trace_id, parent_trace_id)
312-
self.assertEqual(child.span.unwrap().parent, parent.unwrap())
313+
self.assertEqual(
314+
child.span.unwrap().parent, parent.unwrap().get_context()
315+
)
313316

314317
with self.shim.start_span("ParentSpan") as parent:
315318
child = self.shim.start_span("ChildSpan", child_of=parent)
@@ -318,7 +321,9 @@ def test_parent_child_explicit_span(self):
318321
child_trace_id = child.unwrap().get_context().trace_id
319322

320323
self.assertEqual(child_trace_id, parent_trace_id)
321-
self.assertEqual(child.unwrap().parent, parent.unwrap())
324+
self.assertEqual(
325+
child.unwrap().parent, parent.unwrap().get_context()
326+
)
322327

323328
child.finish()
324329

ext/opentelemetry-ext-otcollector/src/opentelemetry/ext/otcollector/trace_exporter/__init__.py

+2-15
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,7 @@ def translate_to_collector(spans: Sequence[Span]):
109109
)
110110

111111
parent_id = 0
112-
if isinstance(span.parent, trace_api.Span):
113-
parent_id = span.parent.get_context().span_id
114-
elif isinstance(span.parent, trace_api.SpanContext):
112+
if span.parent is not None:
115113
parent_id = span.parent.span_id
116114

117115
collector_span.parent_span_id = parent_id.to_bytes(8, "big")
@@ -157,18 +155,7 @@ def translate_to_collector(spans: Sequence[Span]):
157155
collector_span_link.type = (
158156
trace_pb2.Span.Link.Type.TYPE_UNSPECIFIED
159157
)
160-
161-
if isinstance(span.parent, trace_api.Span):
162-
if (
163-
link.context.span_id
164-
== span.parent.get_context().span_id
165-
and link.context.trace_id
166-
== span.parent.get_context().trace_id
167-
):
168-
collector_span_link.type = (
169-
trace_pb2.Span.Link.Type.PARENT_LINKED_SPAN
170-
)
171-
elif isinstance(span.parent, trace_api.SpanContext):
158+
if span.parent is not None:
172159
if (
173160
link.context.span_id == span.parent.span_id
174161
and link.context.trace_id == span.parent.trace_id

ext/opentelemetry-ext-otcollector/tests/test_otcollector_trace_exporter.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,10 @@ def test_translate_to_collector(self):
135135
kind=trace_api.SpanKind.SERVER,
136136
)
137137
span_3 = trace.Span(
138-
name="test3", context=other_context, links=(link_2,), parent=span_2
138+
name="test3",
139+
context=other_context,
140+
links=(link_2,),
141+
parent=span_2.get_context(),
139142
)
140143
otel_spans = [span_1, span_2, span_3]
141144
otel_spans[0].start(start_time=start_times[0])

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ class Span(trace_api.Span):
198198
Args:
199199
name: The name of the operation this span represents
200200
context: The immutable span context
201-
parent: This span's parent, may be a `SpanContext` if the parent is
202-
remote, null if this is a root span
201+
parent: This span's parent's `SpanContext`, or
202+
null if this is a root span
203203
sampler: The sampler used to create this span
204204
trace_config: TODO
205205
resource: Entity producing telemetry
@@ -219,7 +219,7 @@ def __init__(
219219
self,
220220
name: str,
221221
context: trace_api.SpanContext,
222-
parent: trace_api.ParentSpan = None,
222+
parent: Optional[trace_api.SpanContext] = None,
223223
sampler: Optional[sampling.Sampler] = None,
224224
trace_config: None = None, # TODO
225225
resource: None = None,
@@ -594,7 +594,7 @@ def start_span( # pylint: disable=too-many-locals
594594
if parent_context is not None and not isinstance(
595595
parent_context, trace_api.SpanContext
596596
):
597-
raise TypeError
597+
raise TypeError("parent must be a Span, SpanContext or None.")
598598

599599
if parent_context is None or not parent_context.is_valid():
600600
parent = parent_context = None
@@ -640,7 +640,7 @@ def start_span( # pylint: disable=too-many-locals
640640
span = Span(
641641
name=name,
642642
context=context,
643-
parent=parent,
643+
parent=parent_context,
644644
sampler=self.source.sampler,
645645
resource=self.source.resource,
646646
attributes=span_attributes,

opentelemetry-sdk/tests/context/test_asyncio.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,4 @@ def test_with_asyncio(self):
108108
for span in span_list:
109109
if span is expected_parent:
110110
continue
111-
self.assertEqual(span.parent, expected_parent)
111+
self.assertEqual(span.parent, expected_parent.get_context())

opentelemetry-sdk/tests/trace/test_trace.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ def test_start_span_implicit(self):
243243
with tracer.start_span(
244244
"child", kind=trace_api.SpanKind.CLIENT
245245
) as child:
246-
self.assertIs(child.parent, root)
246+
self.assertIs(child.parent, root.get_context())
247247
self.assertEqual(child.kind, trace_api.SpanKind.CLIENT)
248248

249249
self.assertIsNotNone(child.start_time)
@@ -332,7 +332,7 @@ def test_start_as_current_span_implicit(self):
332332

333333
with tracer.start_as_current_span("child") as child:
334334
self.assertIs(tracer.get_current_span(), child)
335-
self.assertIs(child.parent, root)
335+
self.assertIs(child.parent, root.get_context())
336336

337337
# After exiting the child's scope the parent should become the
338338
# current span again.

0 commit comments

Comments
 (0)