@temporalio/interceptors-opentelemetry 1.13.2 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,17 +8,31 @@ import type {
8
8
  ContinueAsNewInput,
9
9
  DisposeInput,
10
10
  GetLogAttributesInput,
11
+ GetMetricTagsInput,
11
12
  LocalActivityInput,
12
13
  Next,
14
+ QueryInput,
13
15
  SignalInput,
14
16
  SignalWorkflowInput,
15
17
  StartChildWorkflowExecutionInput,
18
+ UpdateInput,
16
19
  WorkflowExecuteInput,
17
20
  WorkflowInboundCallsInterceptor,
18
21
  WorkflowInternalsInterceptor,
19
22
  WorkflowOutboundCallsInterceptor,
23
+ StartNexusOperationInput,
24
+ StartNexusOperationOutput,
20
25
  } from '@temporalio/workflow';
21
- import { instrument, extractContextFromHeaders, headersWithContext } from '../instrumentation';
26
+ import {
27
+ instrument,
28
+ instrumentSync,
29
+ extractContextFromHeaders,
30
+ headersWithContext,
31
+ UPDATE_ID_ATTR_KEY,
32
+ NEXUS_SERVICE_ATTR_KEY,
33
+ NEXUS_OPERATION_ATTR_KEY,
34
+ NEXUS_ENDPOINT_ATTR_KEY,
35
+ } from '../instrumentation';
22
36
  import { ContextManager } from './context-manager';
23
37
  import { SpanName, SPAN_DELIMITER } from './definitions';
24
38
  import { SpanExporter } from './span-exporter';
@@ -87,7 +101,57 @@ export class OpenTelemetryInboundInterceptor implements WorkflowInboundCallsInte
87
101
 
88
102
  return await instrument({
89
103
  tracer: this.tracer,
90
- spanName: `${SpanName.WORKFLOW_SIGNAL}${SPAN_DELIMITER}${input.signalName}`,
104
+ spanName: `${SpanName.WORKFLOW_HANDLE_SIGNAL}${SPAN_DELIMITER}${input.signalName}`,
105
+ fn: () => next(input),
106
+ context,
107
+ });
108
+ }
109
+
110
+ public async handleUpdate(
111
+ input: UpdateInput,
112
+ next: Next<WorkflowInboundCallsInterceptor, 'handleUpdate'>
113
+ ): Promise<unknown> {
114
+ if (!hasSdkFlag('OpenTelemetryInterceptorsInstrumentsAllMethods')) return next(input);
115
+
116
+ const context = extractContextFromHeaders(input.headers);
117
+
118
+ return await instrument({
119
+ tracer: this.tracer,
120
+ spanName: `${SpanName.WORKFLOW_HANDLE_UPDATE}${SPAN_DELIMITER}${input.name}`,
121
+ fn: (span) => {
122
+ span.setAttribute(UPDATE_ID_ATTR_KEY, input.updateId);
123
+ return next(input);
124
+ },
125
+ context,
126
+ });
127
+ }
128
+
129
+ public validateUpdate(input: UpdateInput, next: Next<WorkflowInboundCallsInterceptor, 'validateUpdate'>): void {
130
+ if (!hasSdkFlag('OpenTelemetryInterceptorsInstrumentsAllMethods')) return next(input);
131
+
132
+ const context = extractContextFromHeaders(input.headers);
133
+ instrumentSync({
134
+ tracer: this.tracer,
135
+ spanName: `${SpanName.WORKFLOW_VALIDATE_UPDATE}${SPAN_DELIMITER}${input.name}`,
136
+ fn: (span) => {
137
+ span.setAttribute(UPDATE_ID_ATTR_KEY, input.updateId);
138
+ return next(input);
139
+ },
140
+ context,
141
+ });
142
+ }
143
+
144
+ public async handleQuery(
145
+ input: QueryInput,
146
+ next: Next<WorkflowInboundCallsInterceptor, 'handleQuery'>
147
+ ): Promise<unknown> {
148
+ if (!hasSdkFlag('OpenTelemetryInterceptorsInstrumentsAllMethods')) return next(input);
149
+
150
+ const context = extractContextFromHeaders(input.headers);
151
+
152
+ return await instrument({
153
+ tracer: this.tracer,
154
+ spanName: `${SpanName.WORKFLOW_HANDLE_QUERY}${SPAN_DELIMITER}${input.queryName}`,
91
155
  fn: () => next(input),
92
156
  context,
93
157
  });
@@ -149,6 +213,24 @@ export class OpenTelemetryOutboundInterceptor implements WorkflowOutboundCallsIn
149
213
  });
150
214
  }
151
215
 
216
+ public async startNexusOperation(
217
+ input: StartNexusOperationInput,
218
+ next: Next<WorkflowOutboundCallsInterceptor, 'startNexusOperation'>
219
+ ): Promise<StartNexusOperationOutput> {
220
+ if (!hasSdkFlag('OpenTelemetryInterceptorsInstrumentsAllMethods')) return next(input);
221
+
222
+ return await instrument({
223
+ tracer: this.tracer,
224
+ spanName: `${SpanName.NEXUS_OPERATION_START}${SPAN_DELIMITER}${input.service}${SPAN_DELIMITER}${input.operation}`,
225
+ fn: async (span) => {
226
+ span.setAttribute(NEXUS_SERVICE_ATTR_KEY, input.service);
227
+ span.setAttribute(NEXUS_OPERATION_ATTR_KEY, input.operation);
228
+ span.setAttribute(NEXUS_ENDPOINT_ATTR_KEY, input.endpoint);
229
+ return await next(input);
230
+ },
231
+ });
232
+ }
233
+
152
234
  public async startChildWorkflowExecution(
153
235
  input: StartChildWorkflowExecutionInput,
154
236
  next: Next<WorkflowOutboundCallsInterceptor, 'startChildWorkflowExecution'>
@@ -225,6 +307,24 @@ export class OpenTelemetryOutboundInterceptor implements WorkflowOutboundCallsIn
225
307
  return next(input);
226
308
  }
227
309
  }
310
+
311
+ public getMetricTags(
312
+ input: GetMetricTagsInput,
313
+ next: Next<WorkflowOutboundCallsInterceptor, 'getMetricTags'>
314
+ ): GetMetricTagsInput {
315
+ const span = otel.trace.getSpan(otel.context.active());
316
+ const spanContext = span?.spanContext();
317
+ if (spanContext && otel.isSpanContextValid(spanContext)) {
318
+ return next({
319
+ trace_id: spanContext.traceId,
320
+ span_id: spanContext.spanId,
321
+ trace_flags: `0${spanContext.traceFlags.toString(16)}`,
322
+ ...input,
323
+ });
324
+ } else {
325
+ return next(input);
326
+ }
327
+ }
228
328
  }
229
329
 
230
330
  export class OpenTelemetryInternalsInterceptor implements WorkflowInternalsInterceptor {