@@ -158,8 +158,9 @@ def _start_as_current_span(
158
158
* ,
159
159
attributes : opentelemetry .util .types .Attributes ,
160
160
input : Optional [_InputWithHeaders ] = None ,
161
+ kind : opentelemetry .trace .SpanKind ,
161
162
) -> 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 ):
163
164
if input :
164
165
input .headers = self ._context_to_headers (input .headers )
165
166
yield None
@@ -190,6 +191,7 @@ def _completed_workflow_span(
190
191
attributes = params .attributes ,
191
192
links = links ,
192
193
start_time = params .time_ns ,
194
+ kind = params .kind ,
193
195
)
194
196
context = opentelemetry .trace .set_span_in_context (span , context )
195
197
if params .exception :
@@ -218,6 +220,7 @@ async def start_workflow(
218
220
f"{ prefix } :{ input .workflow } " ,
219
221
attributes = {"temporalWorkflowID" : input .id },
220
222
input = input ,
223
+ kind = opentelemetry .trace .SpanKind .CLIENT ,
221
224
):
222
225
return await super ().start_workflow (input )
223
226
@@ -226,6 +229,7 @@ async def query_workflow(self, input: temporalio.client.QueryWorkflowInput) -> A
226
229
f"QueryWorkflow:{ input .query } " ,
227
230
attributes = {"temporalWorkflowID" : input .id },
228
231
input = input ,
232
+ kind = opentelemetry .trace .SpanKind .CLIENT ,
229
233
):
230
234
return await super ().query_workflow (input )
231
235
@@ -236,6 +240,7 @@ async def signal_workflow(
236
240
f"SignalWorkflow:{ input .signal } " ,
237
241
attributes = {"temporalWorkflowID" : input .id },
238
242
input = input ,
243
+ kind = opentelemetry .trace .SpanKind .CLIENT ,
239
244
):
240
245
return await super ().signal_workflow (input )
241
246
@@ -261,6 +266,7 @@ async def execute_activity(
261
266
"temporalRunID" : info .workflow_run_id ,
262
267
"temporalActivityID" : info .activity_id ,
263
268
},
269
+ kind = opentelemetry .trace .SpanKind .SERVER ,
264
270
):
265
271
return await super ().execute_activity (input )
266
272
@@ -283,6 +289,7 @@ class _CompletedWorkflowSpanParams:
283
289
time_ns : int
284
290
link_context : Optional [_CarrierDict ]
285
291
exception : Optional [Exception ]
292
+ kind : opentelemetry .trace .SpanKind
286
293
287
294
288
295
_interceptor_context_key = opentelemetry .context .create_key (
@@ -334,8 +341,10 @@ async def execute_workflow(
334
341
:py:meth:`temporalio.worker.WorkflowInboundInterceptor.execute_workflow`.
335
342
"""
336
343
with self ._top_level_workflow_context (success_is_complete = True ):
344
+ # Entrypoint of workflow should be `server` in OTel
337
345
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 ,
339
348
)
340
349
return await super ().execute_workflow (input )
341
350
@@ -355,6 +364,7 @@ async def handle_signal(self, input: temporalio.worker.HandleSignalInput) -> Non
355
364
self ._completed_span (
356
365
f"HandleSignal:{ input .signal } " ,
357
366
link_context_carrier = link_context_carrier ,
367
+ kind = opentelemetry .trace .SpanKind .SERVER ,
358
368
)
359
369
await super ().handle_signal (input )
360
370
@@ -388,6 +398,7 @@ async def handle_query(self, input: temporalio.worker.HandleQueryInput) -> Any:
388
398
link_context_carrier = link_context_carrier ,
389
399
# Create even on replay for queries
390
400
new_span_even_on_replay = True ,
401
+ kind = opentelemetry .trace .SpanKind .SERVER ,
391
402
)
392
403
return await super ().handle_query (input )
393
404
finally :
@@ -437,6 +448,7 @@ def _top_level_workflow_context(
437
448
self ._completed_span (
438
449
f"CompleteWorkflow:{ temporalio .workflow .info ().workflow_type } " ,
439
450
exception = exception ,
451
+ kind = opentelemetry .trace .SpanKind .INTERNAL ,
440
452
)
441
453
opentelemetry .context .detach (token )
442
454
@@ -468,6 +480,7 @@ def _completed_span(
468
480
new_span_even_on_replay : bool = False ,
469
481
additional_attributes : opentelemetry .util .types .Attributes = None ,
470
482
exception : Optional [Exception ] = None ,
483
+ kind : opentelemetry .trace .SpanKind = opentelemetry .trace .SpanKind .INTERNAL ,
471
484
) -> None :
472
485
# If there is no span on the context, we do not create a span
473
486
if opentelemetry .trace .get_current_span () is opentelemetry .trace .INVALID_SPAN :
@@ -499,6 +512,7 @@ def _completed_span(
499
512
time_ns = temporalio .workflow .time_ns (),
500
513
link_context = link_context_carrier ,
501
514
exception = exception ,
515
+ kind = kind ,
502
516
)
503
517
)
504
518
@@ -535,7 +549,9 @@ async def signal_child_workflow(
535
549
) -> None :
536
550
# Create new span and put on outbound input
537
551
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 ,
539
555
)
540
556
await super ().signal_child_workflow (input )
541
557
@@ -544,7 +560,9 @@ async def signal_external_workflow(
544
560
) -> None :
545
561
# Create new span and put on outbound input
546
562
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 ,
548
566
)
549
567
await super ().signal_external_workflow (input )
550
568
@@ -553,7 +571,9 @@ def start_activity(
553
571
) -> temporalio .workflow .ActivityHandle :
554
572
# Create new span and put on outbound input
555
573
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 ,
557
577
)
558
578
return super ().start_activity (input )
559
579
@@ -562,7 +582,9 @@ async def start_child_workflow(
562
582
) -> temporalio .workflow .ChildWorkflowHandle :
563
583
# Create new span and put on outbound input
564
584
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 ,
566
588
)
567
589
return await super ().start_child_workflow (input )
568
590
@@ -571,7 +593,9 @@ def start_local_activity(
571
593
) -> temporalio .workflow .ActivityHandle :
572
594
# Create new span and put on outbound input
573
595
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 ,
575
599
)
576
600
return super ().start_local_activity (input )
577
601
0 commit comments