Skip to content

Commit d50d274

Browse files
Tracing support improvements (#1819)
feat: support tracing on signals, updates, queries
1 parent 18162b7 commit d50d274

25 files changed

+460
-61
lines changed

temporal-opentracing/src/main/java/io/temporal/opentracing/SpanOperationType.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,14 @@ public enum SpanOperationType {
2727
START_CHILD_WORKFLOW("StartChildWorkflow"),
2828
START_CONTINUE_AS_NEW_WORKFLOW("StartContinueAsNewWorkflow"),
2929
START_ACTIVITY("StartActivity"),
30-
RUN_ACTIVITY("RunActivity");
30+
RUN_ACTIVITY("RunActivity"),
31+
SIGNAL_EXTERNAL_WORKFLOW("SignalExternalWorkflow"),
32+
QUERY_WORKFLOW("QueryWorkflow"),
33+
SIGNAL_WORKFLOW("SignalWorkflow"),
34+
UPDATE_WORKFLOW("UpdateWorkflow"),
35+
HANDLE_QUERY("HandleQuery"),
36+
HANDLE_SIGNAL("HandleSignal"),
37+
HANDLE_UPDATE("HandleUpdate");
3138

3239
private final String defaultPrefix;
3340

temporal-opentracing/src/main/java/io/temporal/opentracing/internal/ActionTypeAndNameSpanBuilderProvider.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,20 @@ protected Map<String, String> getSpanTags(SpanCreationContext context) {
8888
case RUN_WORKFLOW:
8989
case START_ACTIVITY:
9090
case RUN_ACTIVITY:
91+
case SIGNAL_EXTERNAL_WORKFLOW:
92+
case SIGNAL_WORKFLOW:
93+
case UPDATE_WORKFLOW:
94+
case QUERY_WORKFLOW:
95+
case HANDLE_SIGNAL:
96+
case HANDLE_UPDATE:
9197
String runId = context.getRunId();
9298
Preconditions.checkNotNull(
9399
runId, "runId is expected to be not null for span operation type %s", operationType);
94100
return ImmutableMap.of(
95101
StandardTagNames.WORKFLOW_ID, context.getWorkflowId(),
96102
StandardTagNames.RUN_ID, context.getRunId());
103+
case HANDLE_QUERY:
104+
return ImmutableMap.of();
97105
}
98106
throw new IllegalArgumentException("Unknown span operation type provided");
99107
}

temporal-opentracing/src/main/java/io/temporal/opentracing/internal/OpenTracingWorkflowClientCallsInterceptor.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,27 @@ public WorkflowStartOutput start(WorkflowStartInput input) {
5858
}
5959
}
6060

61+
@Override
62+
public WorkflowSignalOutput signal(WorkflowSignalInput input) {
63+
Span workflowSignalSpan =
64+
contextAccessor.writeSpanContextToHeader(
65+
() ->
66+
spanFactory
67+
.createWorkflowSignalSpan(
68+
tracer,
69+
input.getSignalName(),
70+
input.getWorkflowExecution().getWorkflowId(),
71+
input.getWorkflowExecution().getRunId())
72+
.start(),
73+
input.getHeader(),
74+
tracer);
75+
try (Scope ignored = tracer.scopeManager().activate(workflowSignalSpan)) {
76+
return super.signal(input);
77+
} finally {
78+
workflowSignalSpan.finish();
79+
}
80+
}
81+
6182
@Override
6283
public WorkflowSignalWithStartOutput signalWithStart(WorkflowSignalWithStartInput input) {
6384
WorkflowStartInput workflowStartInput = input.getWorkflowStartInput();
@@ -76,6 +97,48 @@ public WorkflowSignalWithStartOutput signalWithStart(WorkflowSignalWithStartInpu
7697
}
7798
}
7899

100+
@Override
101+
public <R> QueryOutput<R> query(QueryInput<R> input) {
102+
Span workflowQuerySpan =
103+
contextAccessor.writeSpanContextToHeader(
104+
() ->
105+
spanFactory
106+
.createWorkflowQuerySpan(
107+
tracer,
108+
input.getQueryType(),
109+
input.getWorkflowExecution().getWorkflowId(),
110+
input.getWorkflowExecution().getRunId())
111+
.start(),
112+
input.getHeader(),
113+
tracer);
114+
try (Scope ignored = tracer.scopeManager().activate(workflowQuerySpan)) {
115+
return super.query(input);
116+
} finally {
117+
workflowQuerySpan.finish();
118+
}
119+
}
120+
121+
@Override
122+
public <R> StartUpdateOutput<R> startUpdate(StartUpdateInput<R> input) {
123+
Span workflowStartUpdateSpan =
124+
contextAccessor.writeSpanContextToHeader(
125+
() ->
126+
spanFactory
127+
.createWorkflowStartUpdateSpan(
128+
tracer,
129+
input.getUpdateName(),
130+
input.getWorkflowExecution().getWorkflowId(),
131+
input.getWorkflowExecution().getRunId())
132+
.start(),
133+
input.getHeader(),
134+
tracer);
135+
try (Scope ignored = tracer.scopeManager().activate(workflowStartUpdateSpan)) {
136+
return super.startUpdate(input);
137+
} finally {
138+
workflowStartUpdateSpan.finish();
139+
}
140+
}
141+
79142
private Tracer.SpanBuilder createWorkflowStartSpanBuilder(
80143
WorkflowStartInput input, SpanOperationType operationType) {
81144
return spanFactory.createWorkflowStartSpan(

temporal-opentracing/src/main/java/io/temporal/opentracing/internal/OpenTracingWorkflowInboundCallsInterceptor.java

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public WorkflowOutput execute(WorkflowInput input) {
6969
Workflow.getInfo().getRunId(),
7070
rootSpanContext)
7171
.start();
72-
try (Scope scope = tracer.scopeManager().activate(workflowRunSpan)) {
72+
try (Scope ignored = tracer.scopeManager().activate(workflowRunSpan)) {
7373
return super.execute(input);
7474
} catch (Throwable t) {
7575
if (t instanceof DestroyWorkflowThreadError) {
@@ -82,4 +82,83 @@ public WorkflowOutput execute(WorkflowInput input) {
8282
workflowRunSpan.finish();
8383
}
8484
}
85+
86+
@Override
87+
public void handleSignal(SignalInput input) {
88+
Tracer tracer = options.getTracer();
89+
SpanContext rootSpanContext =
90+
contextAccessor.readSpanContextFromHeader(input.getHeader(), tracer);
91+
Span workflowSignalSpan =
92+
spanFactory
93+
.createWorkflowHandleSignalSpan(
94+
tracer,
95+
input.getSignalName(),
96+
Workflow.getInfo().getWorkflowId(),
97+
Workflow.getInfo().getRunId(),
98+
rootSpanContext)
99+
.start();
100+
try (Scope ignored = tracer.scopeManager().activate(workflowSignalSpan)) {
101+
super.handleSignal(input);
102+
} catch (Throwable t) {
103+
if (t instanceof DestroyWorkflowThreadError) {
104+
spanFactory.logEviction(workflowSignalSpan);
105+
} else {
106+
spanFactory.logFail(workflowSignalSpan, t);
107+
}
108+
throw t;
109+
} finally {
110+
workflowSignalSpan.finish();
111+
}
112+
}
113+
114+
@Override
115+
public QueryOutput handleQuery(QueryInput input) {
116+
Tracer tracer = options.getTracer();
117+
SpanContext rootSpanContext =
118+
contextAccessor.readSpanContextFromHeader(input.getHeader(), tracer);
119+
Span workflowQuerySpan =
120+
spanFactory
121+
.createWorkflowHandleQuerySpan(tracer, input.getQueryName(), rootSpanContext)
122+
.start();
123+
try (Scope ignored = tracer.scopeManager().activate(workflowQuerySpan)) {
124+
return super.handleQuery(input);
125+
} catch (Throwable t) {
126+
if (t instanceof DestroyWorkflowThreadError) {
127+
spanFactory.logEviction(workflowQuerySpan);
128+
} else {
129+
spanFactory.logFail(workflowQuerySpan, t);
130+
}
131+
throw t;
132+
} finally {
133+
workflowQuerySpan.finish();
134+
}
135+
}
136+
137+
@Override
138+
public UpdateOutput executeUpdate(UpdateInput input) {
139+
Tracer tracer = options.getTracer();
140+
SpanContext rootSpanContext =
141+
contextAccessor.readSpanContextFromHeader(input.getHeader(), tracer);
142+
Span workflowSignalSpan =
143+
spanFactory
144+
.createWorkflowExecuteUpdateSpan(
145+
tracer,
146+
input.getUpdateName(),
147+
Workflow.getInfo().getWorkflowId(),
148+
Workflow.getInfo().getRunId(),
149+
rootSpanContext)
150+
.start();
151+
try (Scope ignored = tracer.scopeManager().activate(workflowSignalSpan)) {
152+
return super.executeUpdate(input);
153+
} catch (Throwable t) {
154+
if (t instanceof DestroyWorkflowThreadError) {
155+
spanFactory.logEviction(workflowSignalSpan);
156+
} else {
157+
spanFactory.logFail(workflowSignalSpan, t);
158+
}
159+
throw t;
160+
} finally {
161+
workflowSignalSpan.finish();
162+
}
163+
}
85164
}

temporal-opentracing/src/main/java/io/temporal/opentracing/internal/OpenTracingWorkflowOutboundCallsInterceptor.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,32 @@ public <R> ChildWorkflowOutput<R> executeChildWorkflow(ChildWorkflowInput<R> inp
100100
}
101101
}
102102

103+
@Override
104+
public SignalExternalOutput signalExternalWorkflow(SignalExternalInput input) {
105+
if (!WorkflowUnsafe.isReplaying()) {
106+
WorkflowInfo workflowInfo = Workflow.getInfo();
107+
Span childWorkflowStartSpan =
108+
contextAccessor.writeSpanContextToHeader(
109+
() ->
110+
spanFactory
111+
.createExternalWorkflowSignalSpan(
112+
tracer,
113+
input.getSignalName(),
114+
workflowInfo.getWorkflowId(),
115+
workflowInfo.getRunId())
116+
.start(),
117+
input.getHeader(),
118+
tracer);
119+
try (Scope ignored = tracer.scopeManager().activate(childWorkflowStartSpan)) {
120+
return super.signalExternalWorkflow(input);
121+
} finally {
122+
childWorkflowStartSpan.finish();
123+
}
124+
} else {
125+
return super.signalExternalWorkflow(input);
126+
}
127+
}
128+
103129
@Override
104130
public void continueAsNew(ContinueAsNewInput input) {
105131
if (!WorkflowUnsafe.isReplaying()) {

temporal-opentracing/src/main/java/io/temporal/opentracing/internal/SpanFactory.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,46 @@ public Tracer.SpanBuilder createChildWorkflowStartSpan(
7777
return createSpan(context, tracer, null, References.CHILD_OF);
7878
}
7979

80+
public Tracer.SpanBuilder createExternalWorkflowSignalSpan(
81+
Tracer tracer, String signalName, String workflowId, String runId) {
82+
SpanCreationContext context =
83+
SpanCreationContext.newBuilder()
84+
.setSpanOperationType(SpanOperationType.SIGNAL_EXTERNAL_WORKFLOW)
85+
.setActionName(signalName)
86+
.setWorkflowId(workflowId)
87+
.setRunId(runId)
88+
.build();
89+
return createSpan(context, tracer, null, References.FOLLOWS_FROM);
90+
}
91+
92+
public Tracer.SpanBuilder createWorkflowSignalSpan(
93+
Tracer tracer, String signalName, String workflowId, String runId) {
94+
SpanCreationContext context =
95+
SpanCreationContext.newBuilder()
96+
.setSpanOperationType(SpanOperationType.SIGNAL_WORKFLOW)
97+
.setActionName(signalName)
98+
.setWorkflowId(workflowId)
99+
.setRunId(runId)
100+
.build();
101+
return createSpan(context, tracer, null, References.FOLLOWS_FROM);
102+
}
103+
104+
public Tracer.SpanBuilder createWorkflowHandleSignalSpan(
105+
Tracer tracer,
106+
String signalName,
107+
String workflowId,
108+
String runId,
109+
SpanContext workflowSignalSpanContext) {
110+
SpanCreationContext context =
111+
SpanCreationContext.newBuilder()
112+
.setSpanOperationType(SpanOperationType.HANDLE_SIGNAL)
113+
.setActionName(signalName)
114+
.setWorkflowId(workflowId)
115+
.setRunId(runId)
116+
.build();
117+
return createSpan(context, tracer, workflowSignalSpanContext, References.FOLLOWS_FROM);
118+
}
119+
80120
public Tracer.SpanBuilder createContinueAsNewWorkflowStartSpan(
81121
Tracer tracer, String continueAsNewWorkflowType, String workflowId, String parentRunId) {
82122
SpanCreationContext context =
@@ -133,6 +173,56 @@ public Tracer.SpanBuilder createActivityRunSpan(
133173
return createSpan(context, tracer, activityStartSpanContext, References.FOLLOWS_FROM);
134174
}
135175

176+
public Tracer.SpanBuilder createWorkflowStartUpdateSpan(
177+
Tracer tracer, String updateName, String workflowId, String runId) {
178+
SpanCreationContext context =
179+
SpanCreationContext.newBuilder()
180+
.setSpanOperationType(SpanOperationType.UPDATE_WORKFLOW)
181+
.setActionName(updateName)
182+
.setWorkflowId(workflowId)
183+
.setRunId(runId)
184+
.build();
185+
return createSpan(context, tracer, null, References.FOLLOWS_FROM);
186+
}
187+
188+
public Tracer.SpanBuilder createWorkflowExecuteUpdateSpan(
189+
Tracer tracer,
190+
String updateName,
191+
String workflowId,
192+
String runId,
193+
SpanContext workflowUpdateSpanContext) {
194+
SpanCreationContext context =
195+
SpanCreationContext.newBuilder()
196+
.setSpanOperationType(SpanOperationType.HANDLE_UPDATE)
197+
.setActionName(updateName)
198+
.setWorkflowId(workflowId)
199+
.setRunId(runId)
200+
.build();
201+
return createSpan(context, tracer, workflowUpdateSpanContext, References.FOLLOWS_FROM);
202+
}
203+
204+
public Tracer.SpanBuilder createWorkflowQuerySpan(
205+
Tracer tracer, String updateName, String workflowId, String runId) {
206+
SpanCreationContext context =
207+
SpanCreationContext.newBuilder()
208+
.setSpanOperationType(SpanOperationType.QUERY_WORKFLOW)
209+
.setActionName(updateName)
210+
.setWorkflowId(workflowId)
211+
.setRunId(runId)
212+
.build();
213+
return createSpan(context, tracer, null, References.FOLLOWS_FROM);
214+
}
215+
216+
public Tracer.SpanBuilder createWorkflowHandleQuerySpan(
217+
Tracer tracer, String queryName, SpanContext workflowQuerySpanContext) {
218+
SpanCreationContext context =
219+
SpanCreationContext.newBuilder()
220+
.setSpanOperationType(SpanOperationType.HANDLE_QUERY)
221+
.setActionName(queryName)
222+
.build();
223+
return createSpan(context, tracer, workflowQuerySpanContext, References.FOLLOWS_FROM);
224+
}
225+
136226
@SuppressWarnings("deprecation")
137227
public void logFail(Span toSpan, Throwable failReason) {
138228
toSpan.setTag(StandardTagNames.FAILED, true);

temporal-opentracing/src/test/java/io/temporal/opentracing/SignalWithStartTest.java

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,24 @@ public void signalWithStart() {
121121
assertEquals(clientSpan.context().spanId(), workflowStartSpan.parentId());
122122
assertEquals("SignalWithStartWorkflow:TestWorkflow", workflowStartSpan.operationName());
123123

124-
List<MockSpan> workflowRunSpans = spansHelper.getByParentSpan(workflowStartSpan);
125-
assertEquals(1, workflowRunSpans.size());
126-
127-
MockSpan workflowRunSpan = workflowRunSpans.get(0);
128-
assertEquals(workflowStartSpan.context().spanId(), workflowRunSpan.parentId());
129-
assertEquals("RunWorkflow:TestWorkflow", workflowRunSpan.operationName());
124+
if (SDKTestWorkflowRule.useExternalService) {
125+
List<MockSpan> workflowSpans = spansHelper.getByParentSpan(workflowStartSpan);
126+
assertEquals(2, workflowSpans.size());
127+
128+
MockSpan workflowSignalSpan = workflowSpans.get(0);
129+
assertEquals(workflowStartSpan.context().spanId(), workflowSignalSpan.parentId());
130+
assertEquals("HandleSignal:signal", workflowSignalSpan.operationName());
131+
132+
MockSpan workflowRunSpan = workflowSpans.get(1);
133+
assertEquals(workflowStartSpan.context().spanId(), workflowRunSpan.parentId());
134+
assertEquals("RunWorkflow:TestWorkflow", workflowRunSpan.operationName());
135+
} else {
136+
List<MockSpan> workflowRunSpans = spansHelper.getByParentSpan(workflowStartSpan);
137+
assertEquals(1, workflowRunSpans.size());
138+
139+
MockSpan workflowRunSpan = workflowRunSpans.get(0);
140+
assertEquals(workflowStartSpan.context().spanId(), workflowRunSpan.parentId());
141+
assertEquals("RunWorkflow:TestWorkflow", workflowRunSpan.operationName());
142+
}
130143
}
131144
}

0 commit comments

Comments
 (0)