Skip to content

Commit 393e5c8

Browse files
authored
Provide Span.Kind for TracingInterceptor (#356)
1 parent 3fec58f commit 393e5c8

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

temporalio/contrib/opentelemetry.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,9 @@ def _start_as_current_span(
158158
*,
159159
attributes: opentelemetry.util.types.Attributes,
160160
input: Optional[_InputWithHeaders] = None,
161+
kind: opentelemetry.trace.SpanKind,
161162
) -> Iterator[None]:
162-
with self.tracer.start_as_current_span(name, attributes=attributes):
163+
with self.tracer.start_as_current_span(name, attributes=attributes, kind=kind):
163164
if input:
164165
input.headers = self._context_to_headers(input.headers)
165166
yield None
@@ -190,6 +191,7 @@ def _completed_workflow_span(
190191
attributes=params.attributes,
191192
links=links,
192193
start_time=params.time_ns,
194+
kind=params.kind,
193195
)
194196
context = opentelemetry.trace.set_span_in_context(span, context)
195197
if params.exception:
@@ -218,6 +220,7 @@ async def start_workflow(
218220
f"{prefix}:{input.workflow}",
219221
attributes={"temporalWorkflowID": input.id},
220222
input=input,
223+
kind=opentelemetry.trace.SpanKind.CLIENT,
221224
):
222225
return await super().start_workflow(input)
223226

@@ -226,6 +229,7 @@ async def query_workflow(self, input: temporalio.client.QueryWorkflowInput) -> A
226229
f"QueryWorkflow:{input.query}",
227230
attributes={"temporalWorkflowID": input.id},
228231
input=input,
232+
kind=opentelemetry.trace.SpanKind.CLIENT,
229233
):
230234
return await super().query_workflow(input)
231235

@@ -236,6 +240,7 @@ async def signal_workflow(
236240
f"SignalWorkflow:{input.signal}",
237241
attributes={"temporalWorkflowID": input.id},
238242
input=input,
243+
kind=opentelemetry.trace.SpanKind.CLIENT,
239244
):
240245
return await super().signal_workflow(input)
241246

@@ -261,6 +266,7 @@ async def execute_activity(
261266
"temporalRunID": info.workflow_run_id,
262267
"temporalActivityID": info.activity_id,
263268
},
269+
kind=opentelemetry.trace.SpanKind.SERVER,
264270
):
265271
return await super().execute_activity(input)
266272

@@ -283,6 +289,7 @@ class _CompletedWorkflowSpanParams:
283289
time_ns: int
284290
link_context: Optional[_CarrierDict]
285291
exception: Optional[Exception]
292+
kind: opentelemetry.trace.SpanKind
286293

287294

288295
_interceptor_context_key = opentelemetry.context.create_key(
@@ -334,8 +341,10 @@ async def execute_workflow(
334341
:py:meth:`temporalio.worker.WorkflowInboundInterceptor.execute_workflow`.
335342
"""
336343
with self._top_level_workflow_context(success_is_complete=True):
344+
# Entrypoint of workflow should be `server` in OTel
337345
self._completed_span(
338-
f"RunWorkflow:{temporalio.workflow.info().workflow_type}"
346+
f"RunWorkflow:{temporalio.workflow.info().workflow_type}",
347+
kind=opentelemetry.trace.SpanKind.SERVER,
339348
)
340349
return await super().execute_workflow(input)
341350

@@ -355,6 +364,7 @@ async def handle_signal(self, input: temporalio.worker.HandleSignalInput) -> Non
355364
self._completed_span(
356365
f"HandleSignal:{input.signal}",
357366
link_context_carrier=link_context_carrier,
367+
kind=opentelemetry.trace.SpanKind.SERVER,
358368
)
359369
await super().handle_signal(input)
360370

@@ -388,6 +398,7 @@ async def handle_query(self, input: temporalio.worker.HandleQueryInput) -> Any:
388398
link_context_carrier=link_context_carrier,
389399
# Create even on replay for queries
390400
new_span_even_on_replay=True,
401+
kind=opentelemetry.trace.SpanKind.SERVER,
391402
)
392403
return await super().handle_query(input)
393404
finally:
@@ -437,6 +448,7 @@ def _top_level_workflow_context(
437448
self._completed_span(
438449
f"CompleteWorkflow:{temporalio.workflow.info().workflow_type}",
439450
exception=exception,
451+
kind=opentelemetry.trace.SpanKind.INTERNAL,
440452
)
441453
opentelemetry.context.detach(token)
442454

@@ -468,6 +480,7 @@ def _completed_span(
468480
new_span_even_on_replay: bool = False,
469481
additional_attributes: opentelemetry.util.types.Attributes = None,
470482
exception: Optional[Exception] = None,
483+
kind: opentelemetry.trace.SpanKind = opentelemetry.trace.SpanKind.INTERNAL,
471484
) -> None:
472485
# If there is no span on the context, we do not create a span
473486
if opentelemetry.trace.get_current_span() is opentelemetry.trace.INVALID_SPAN:
@@ -499,6 +512,7 @@ def _completed_span(
499512
time_ns=temporalio.workflow.time_ns(),
500513
link_context=link_context_carrier,
501514
exception=exception,
515+
kind=kind,
502516
)
503517
)
504518

@@ -535,7 +549,9 @@ async def signal_child_workflow(
535549
) -> None:
536550
# Create new span and put on outbound input
537551
self.root._completed_span(
538-
f"SignalChildWorkflow:{input.signal}", add_to_outbound=input
552+
f"SignalChildWorkflow:{input.signal}",
553+
add_to_outbound=input,
554+
kind=opentelemetry.trace.SpanKind.SERVER,
539555
)
540556
await super().signal_child_workflow(input)
541557

@@ -544,7 +560,9 @@ async def signal_external_workflow(
544560
) -> None:
545561
# Create new span and put on outbound input
546562
self.root._completed_span(
547-
f"SignalExternalWorkflow:{input.signal}", add_to_outbound=input
563+
f"SignalExternalWorkflow:{input.signal}",
564+
add_to_outbound=input,
565+
kind=opentelemetry.trace.SpanKind.CLIENT,
548566
)
549567
await super().signal_external_workflow(input)
550568

@@ -553,7 +571,9 @@ def start_activity(
553571
) -> temporalio.workflow.ActivityHandle:
554572
# Create new span and put on outbound input
555573
self.root._completed_span(
556-
f"StartActivity:{input.activity}", add_to_outbound=input
574+
f"StartActivity:{input.activity}",
575+
add_to_outbound=input,
576+
kind=opentelemetry.trace.SpanKind.CLIENT,
557577
)
558578
return super().start_activity(input)
559579

@@ -562,7 +582,9 @@ async def start_child_workflow(
562582
) -> temporalio.workflow.ChildWorkflowHandle:
563583
# Create new span and put on outbound input
564584
self.root._completed_span(
565-
f"StartChildWorkflow:{input.workflow}", add_to_outbound=input
585+
f"StartChildWorkflow:{input.workflow}",
586+
add_to_outbound=input,
587+
kind=opentelemetry.trace.SpanKind.CLIENT,
566588
)
567589
return await super().start_child_workflow(input)
568590

@@ -571,7 +593,9 @@ def start_local_activity(
571593
) -> temporalio.workflow.ActivityHandle:
572594
# Create new span and put on outbound input
573595
self.root._completed_span(
574-
f"StartActivity:{input.activity}", add_to_outbound=input
596+
f"StartActivity:{input.activity}",
597+
add_to_outbound=input,
598+
kind=opentelemetry.trace.SpanKind.CLIENT,
575599
)
576600
return super().start_local_activity(input)
577601

0 commit comments

Comments
 (0)