@aws/durable-execution-sdk-js-otel 0.0.1 → 0.1.1

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.
@@ -0,0 +1,546 @@
1
+ 'use strict';
2
+
3
+ var api = require('@opentelemetry/api');
4
+ var instrumentationAwsSdk = require('@opentelemetry/instrumentation-aws-sdk');
5
+ var instrumentation = require('@opentelemetry/instrumentation');
6
+ var node_crypto = require('node:crypto');
7
+
8
+ /**
9
+ * A custom OpenTelemetry IdGenerator that produces deterministic trace and span IDs
10
+ * derived from execution metadata (X-Ray headers, execution ARNs, operation IDs)
11
+ * rather than random values.
12
+ *
13
+ * This ensures that spans from different Lambda invocations of the same durable
14
+ * execution are stitched into a single coherent trace.
15
+ */
16
+ class DeterministicIdGenerator {
17
+ traceId;
18
+ nextSpanId;
19
+ /**
20
+ * Set the trace ID for all subsequent generateTraceId() calls.
21
+ * This is persistent until setTraceId is called again.
22
+ */
23
+ setTraceId(traceId) {
24
+ this.traceId = traceId;
25
+ }
26
+ /**
27
+ * Set the span ID to return on the next single generateSpanId() call.
28
+ * This is a one-shot override: it is consumed on the next call and then
29
+ * reverts to default behavior.
30
+ */
31
+ setNextSpanId(spanId) {
32
+ this.nextSpanId = spanId;
33
+ }
34
+ /**
35
+ * Generate a 32-char lowercase hex trace ID.
36
+ *
37
+ * If setTraceId has been called, returns that value persistently.
38
+ * Otherwise returns a random 32-char hex string as fallback.
39
+ */
40
+ generateTraceId() {
41
+ if (this.traceId) {
42
+ return this.traceId;
43
+ }
44
+ // Fallback: generate a random trace ID
45
+ return node_crypto.createHash("sha256")
46
+ .update(Math.random().toString())
47
+ .digest("hex")
48
+ .slice(0, 32);
49
+ }
50
+ /**
51
+ * Generate a 16-char lowercase hex span ID.
52
+ *
53
+ * If setNextSpanId has been called, returns that value once (one-shot)
54
+ * and then clears it. Otherwise returns a random 16-char hex string.
55
+ */
56
+ generateSpanId() {
57
+ if (this.nextSpanId) {
58
+ const spanId = this.nextSpanId;
59
+ this.nextSpanId = undefined;
60
+ return spanId;
61
+ }
62
+ // Fallback: generate a random span ID
63
+ return node_crypto.createHash("sha256")
64
+ .update(Math.random().toString())
65
+ .digest("hex")
66
+ .slice(0, 16);
67
+ }
68
+ }
69
+ /**
70
+ * Derive a deterministic trace ID from an X-Ray Root field.
71
+ * Strips the `Root=1-` prefix and all `-` separators to produce
72
+ * a valid 32-character lowercase hex OpenTelemetry trace ID.
73
+ *
74
+ * @param xRayRoot - The Root field value, e.g. "1-5759e988-bd862e3fe1be46a994272793"
75
+ * @returns A 32-char lowercase hex string, or undefined if the input is invalid
76
+ */
77
+ function deriveTraceIdFromXRayRoot(xRayRoot) {
78
+ // Strip "Root=" prefix if present
79
+ let root = xRayRoot;
80
+ if (root.startsWith("Root=")) {
81
+ root = root.slice(5);
82
+ }
83
+ // Strip the version prefix "1-"
84
+ if (root.startsWith("1-")) {
85
+ root = root.slice(2);
86
+ }
87
+ else {
88
+ return undefined;
89
+ }
90
+ // Remove all dashes
91
+ const hex = root.replace(/-/g, "");
92
+ // Validate: must be exactly 32 lowercase hex characters
93
+ if (hex.length !== 32 || !/^[0-9a-f]{32}$/.test(hex)) {
94
+ return undefined;
95
+ }
96
+ return hex;
97
+ }
98
+ /**
99
+ * Derive a deterministic trace ID from an execution ARN by hashing it
100
+ * with SHA-256 and truncating to the first 32 lowercase hex characters.
101
+ *
102
+ * @param executionArn - The execution ARN string
103
+ * @returns A 32-char lowercase hex string
104
+ */
105
+ function deriveTraceIdFromArn(executionArn) {
106
+ return node_crypto.createHash("sha256").update(executionArn).digest("hex").slice(0, 32);
107
+ }
108
+ /**
109
+ * Derive a deterministic span ID from an operation ID scoped to a specific execution.
110
+ * Hashes `executionArn + ":" + operationId` with SHA-256 and truncates to the first
111
+ * 16 lowercase hex characters.
112
+ *
113
+ * The executionArn is included in the hash input to avoid span ID collisions when
114
+ * different executions (e.g., a parent and child workflow) share the same trace and
115
+ * have operations at the same positional ID.
116
+ *
117
+ * @param operationId - The operation ID string (positional identifier within an execution)
118
+ * @param executionArn - The execution ARN, used to scope span IDs per execution
119
+ * @returns A 16-char lowercase hex string
120
+ */
121
+ function deriveSpanIdFromOperationId(operationId, executionArn) {
122
+ return node_crypto.createHash("sha256")
123
+ .update(executionArn + ":" + operationId)
124
+ .digest("hex")
125
+ .slice(0, 16);
126
+ }
127
+
128
+ /**
129
+ * Reads the X-Ray trace header from the `_X_AMZN_TRACE_ID` environment variable.
130
+ *
131
+ * The durable execution backend propagates the same Root trace ID to every
132
+ * invocation, so all invocations of the same execution share one traceId.
133
+ *
134
+ * X-Ray Header format:
135
+ * Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1
136
+ *
137
+ * - Extract Root value, strip "1-" prefix and all "-" to get 32-char hex traceId
138
+ * - Extract Parent value for parentSpanId (16-char hex)
139
+ *
140
+ * Returns undefined when _X_AMZN_TRACE_ID is missing or malformed.
141
+ */
142
+ function xRayContextExtractor(_info) {
143
+ const header = process.env._X_AMZN_TRACE_ID;
144
+ if (!header) {
145
+ return undefined;
146
+ }
147
+ // Parse the header into key-value pairs separated by semicolons
148
+ const fields = new Map();
149
+ for (const part of header.split(";")) {
150
+ const eqIdx = part.indexOf("=");
151
+ if (eqIdx > 0) {
152
+ const key = part.slice(0, eqIdx).trim();
153
+ const value = part.slice(eqIdx + 1).trim();
154
+ fields.set(key, value);
155
+ }
156
+ }
157
+ const root = fields.get("Root");
158
+ if (!root) {
159
+ return undefined;
160
+ }
161
+ // Root format: 1-5759e988-bd862e3fe1be46a994272793
162
+ // Strip the "1-" prefix and remove all dashes to get 32-char hex
163
+ const rootValue = root.startsWith("1-") ? root.slice(2) : root;
164
+ const traceId = rootValue.replace(/-/g, "").toLowerCase();
165
+ // Validate: must be exactly 32 hex characters
166
+ if (!/^[0-9a-f]{32}$/.test(traceId)) {
167
+ return undefined;
168
+ }
169
+ const parent = fields.get("Parent");
170
+ let parentSpanId;
171
+ if (parent && /^[0-9a-f]{16}$/.test(parent.toLowerCase())) {
172
+ parentSpanId = parent.toLowerCase();
173
+ }
174
+ return { traceId, parentSpanId };
175
+ }
176
+ /**
177
+ * Reads W3C traceparent from `context.clientContext.custom.traceparent`.
178
+ *
179
+ * W3C traceparent format:
180
+ * 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
181
+ * Format: version-traceId-parentId-traceFlags
182
+ *
183
+ * - traceId is 32 hex chars
184
+ * - parentId is 16 hex chars
185
+ * - flags is 2 hex chars (parsed to number)
186
+ *
187
+ * Returns undefined when clientContext or traceparent is missing or malformed.
188
+ */
189
+ function w3cClientContextExtractor(info) {
190
+ const extendedInfo = info;
191
+ const traceparent = extendedInfo.context?.clientContext?.custom?.traceparent;
192
+ if (!traceparent) {
193
+ return undefined;
194
+ }
195
+ return parseW3CTraceparent(traceparent);
196
+ }
197
+ /**
198
+ * Parses a W3C traceparent header value.
199
+ *
200
+ * Format: version-traceId-parentId-flags
201
+ * Example: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
202
+ */
203
+ function parseW3CTraceparent(traceparent) {
204
+ const parts = traceparent.split("-");
205
+ // Must have exactly 4 parts: version, traceId, parentId, flags
206
+ if (parts.length !== 4) {
207
+ return undefined;
208
+ }
209
+ const [version, traceId, parentId, flags] = parts;
210
+ // Version must be 2 hex chars
211
+ if (!/^[0-9a-f]{2}$/.test(version)) {
212
+ return undefined;
213
+ }
214
+ // TraceId must be 32 hex chars
215
+ if (!/^[0-9a-f]{32}$/.test(traceId)) {
216
+ return undefined;
217
+ }
218
+ // ParentId must be 16 hex chars
219
+ if (!/^[0-9a-f]{16}$/.test(parentId)) {
220
+ return undefined;
221
+ }
222
+ // Flags must be 2 hex chars
223
+ if (!/^[0-9a-f]{2}$/.test(flags)) {
224
+ return undefined;
225
+ }
226
+ const traceFlags = parseInt(flags, 16);
227
+ return {
228
+ traceId,
229
+ parentSpanId: parentId,
230
+ traceFlags,
231
+ };
232
+ }
233
+
234
+ const DEFAULT_INSTRUMENTATION_NAME = "aws-durable-execution-sdk-js";
235
+ /**
236
+ * OpenTelemetry instrumentation plugin for durable executions.
237
+ *
238
+ * Implements the DurableInstrumentationPlugin interface to emit distributed
239
+ * traces that correlate across multiple Lambda invocations of a single
240
+ * durable execution.
241
+ */
242
+ class OtelPlugin {
243
+ tracerProvider;
244
+ tracer;
245
+ idGenerator;
246
+ contextExtractor;
247
+ // Per-invocation state
248
+ spanMap = new Map();
249
+ spanStack = [];
250
+ invocationSpan;
251
+ executionArn = "";
252
+ attemptSpan;
253
+ constructor(config) {
254
+ const instrumentationName = config?.instrumentationName ?? DEFAULT_INSTRUMENTATION_NAME;
255
+ this.idGenerator = new DeterministicIdGenerator();
256
+ this.contextExtractor = config?.contextExtractor ?? xRayContextExtractor;
257
+ if (config?.tracerProvider) {
258
+ this.tracerProvider = config.tracerProvider;
259
+ }
260
+ else {
261
+ this.tracerProvider = api.trace.getTracerProvider();
262
+ instrumentation.registerInstrumentations({
263
+ tracerProvider: this.tracerProvider,
264
+ instrumentations: [
265
+ new instrumentationAwsSdk.AwsInstrumentation({
266
+ suppressInternalInstrumentation: true,
267
+ sqsExtractContextPropagationFromPayload: true,
268
+ }),
269
+ ],
270
+ });
271
+ }
272
+ this.tracer = this.tracerProvider.getTracer(instrumentationName);
273
+ // Monkey-patch the tracer's ID generator so spans use deterministic IDs.
274
+ // The _idGenerator field is internal to @opentelemetry/sdk-trace-base's Tracer class.
275
+ this.tracer._idGenerator = this.idGenerator;
276
+ }
277
+ async onInvocationStart(info) {
278
+ // 1. Store the execution ARN
279
+ this.executionArn = info.executionArn;
280
+ // 2. Invoke the context extractor
281
+ const extractedContext = this.contextExtractor(info);
282
+ // 3. Set the trace ID on the ID generator
283
+ if (extractedContext?.traceId) {
284
+ this.idGenerator.setTraceId(extractedContext.traceId);
285
+ }
286
+ else {
287
+ // Fallback: derive trace ID from ARN
288
+ const derivedId = deriveTraceIdFromArn(info.executionArn);
289
+ this.idGenerator.setTraceId(derivedId);
290
+ }
291
+ // 4. Create the invocation span
292
+ this.invocationSpan = this.tracer.startSpan("invocation", {
293
+ attributes: {
294
+ "durable.execution.arn": info.executionArn,
295
+ },
296
+ });
297
+ }
298
+ wrapInvocation(_info, fn) {
299
+ if (!this.invocationSpan) {
300
+ return fn();
301
+ }
302
+ return api.context.with(api.trace.setSpan(api.context.active(), this.invocationSpan), fn);
303
+ }
304
+ async onInvocationEnd(_info) {
305
+ // 1. End all spans in the stack in reverse order
306
+ while (this.spanStack.length > 0) {
307
+ const span = this.spanStack.pop();
308
+ span.end();
309
+ }
310
+ // 2. End the invocation span if it exists
311
+ if (this.invocationSpan) {
312
+ this.invocationSpan.end();
313
+ }
314
+ // 3. Force flush the tracer provider
315
+ if ("forceFlush" in this.tracerProvider) {
316
+ try {
317
+ await this.tracerProvider.forceFlush();
318
+ }
319
+ catch {
320
+ // Gracefully handle flush errors
321
+ }
322
+ }
323
+ // 4. Clear all per-invocation state
324
+ this.spanMap.clear();
325
+ this.spanStack = [];
326
+ this.invocationSpan = undefined;
327
+ this.executionArn = "";
328
+ this.attemptSpan = undefined;
329
+ }
330
+ async onOperationStart(info) {
331
+ const deterministicSpanId = deriveSpanIdFromOperationId(info.id, this.executionArn);
332
+ const spanName = info.name ?? info.type;
333
+ // Resolve parent span: use parentId from map, or fall back to invocation span
334
+ let parentSpan;
335
+ if (info.parentId && this.spanMap.has(info.parentId)) {
336
+ parentSpan = this.spanMap.get(info.parentId);
337
+ }
338
+ else {
339
+ parentSpan = this.invocationSpan;
340
+ }
341
+ const parentContext = parentSpan
342
+ ? api.trace.setSpan(api.context.active(), parentSpan)
343
+ : api.context.active();
344
+ const attributes = {
345
+ "durable.execution.arn": this.executionArn,
346
+ "durable.operation.id": info.id,
347
+ "durable.operation.type": info.type,
348
+ };
349
+ if (info.name) {
350
+ attributes["durable.operation.name"] = info.name;
351
+ }
352
+ if (info.subType) {
353
+ attributes["durable.operation.subtype"] = info.subType;
354
+ }
355
+ let span;
356
+ if (!info.isReplay) {
357
+ // Non-replay: use deterministic span ID
358
+ this.idGenerator.setNextSpanId(deterministicSpanId);
359
+ span = this.tracer.startSpan(spanName, {
360
+ attributes,
361
+ startTime: info.startTimestamp,
362
+ }, parentContext);
363
+ }
364
+ else if (info.type === "CONTEXT" || info.type === "STEP") {
365
+ // Replay: use random span ID, add Link to deterministic span
366
+ const traceId = this.invocationSpan?.spanContext().traceId ??
367
+ this.idGenerator.generateTraceId();
368
+ span = this.tracer.startSpan(spanName, {
369
+ attributes,
370
+ startTime: info.startTimestamp,
371
+ links: [
372
+ {
373
+ context: { traceId, spanId: deterministicSpanId, traceFlags: 1 },
374
+ },
375
+ ],
376
+ }, parentContext);
377
+ }
378
+ // Push to map and stack
379
+ if (span != undefined) {
380
+ this.spanMap.set(info.id, span);
381
+ this.spanStack.push(span);
382
+ }
383
+ }
384
+ wrapChildContextFn(info, fn) {
385
+ const span = this.spanMap.get(info.id);
386
+ if (!span) {
387
+ return fn();
388
+ }
389
+ return api.context.with(api.trace.setSpan(api.context.active(), span), fn);
390
+ }
391
+ async onOperationEnd(info) {
392
+ // Skip span creation for WAIT, INVOKE, CHAINED_INVOKE, and CALLBACK operations on replay
393
+ if (info.isReplay &&
394
+ (info.type === "WAIT" ||
395
+ info.type === "INVOKE" ||
396
+ info.type === "CHAINED_INVOKE" ||
397
+ info.type === "CALLBACK")) {
398
+ return;
399
+ }
400
+ const deterministicSpanId = deriveSpanIdFromOperationId(info.id, this.executionArn);
401
+ if (this.spanMap.has(info.id)) {
402
+ // Operation was started in this invocation
403
+ const span = this.spanMap.get(info.id);
404
+ // Record error if present
405
+ if (info.error) {
406
+ span.setStatus({
407
+ code: api.SpanStatusCode.ERROR,
408
+ message: info.error.message,
409
+ });
410
+ span.recordException(info.error);
411
+ }
412
+ // End the span
413
+ span.end(info.endTimestamp);
414
+ // Remove from map
415
+ this.spanMap.delete(info.id);
416
+ // Remove from stack (find by reference)
417
+ const stackIndex = this.spanStack.indexOf(span);
418
+ if (stackIndex !== -1) {
419
+ this.spanStack.splice(stackIndex, 1);
420
+ }
421
+ }
422
+ else if (!info.isReplay) {
423
+ // Operation was started in a prior invocation — create Continuation_Span
424
+ const spanName = info.name ?? info.type;
425
+ const traceId = this.invocationSpan?.spanContext().traceId ??
426
+ this.idGenerator.generateTraceId();
427
+ const parentContext = this.invocationSpan
428
+ ? api.trace.setSpan(api.context.active(), this.invocationSpan)
429
+ : api.context.active();
430
+ const attributes = {
431
+ "durable.execution.arn": this.executionArn,
432
+ "durable.operation.id": info.id,
433
+ "durable.operation.type": info.type,
434
+ };
435
+ if (info.name) {
436
+ attributes["durable.operation.name"] = info.name;
437
+ }
438
+ if (info.subType) {
439
+ attributes["durable.operation.subtype"] = info.subType;
440
+ }
441
+ const continuationSpan = this.tracer.startSpan(spanName, {
442
+ attributes,
443
+ startTime: info.startTimestamp,
444
+ links: [
445
+ {
446
+ context: { traceId, spanId: deterministicSpanId, traceFlags: 1 },
447
+ },
448
+ ],
449
+ }, parentContext);
450
+ // Record error if present
451
+ if (info.error) {
452
+ continuationSpan.setStatus({
453
+ code: api.SpanStatusCode.ERROR,
454
+ message: info.error.message,
455
+ });
456
+ continuationSpan.recordException(info.error);
457
+ }
458
+ // Immediately end
459
+ continuationSpan.end(info.endTimestamp);
460
+ }
461
+ }
462
+ async onOperationAttemptStart(info) {
463
+ const deterministicSpanId = deriveSpanIdFromOperationId(info.id, this.executionArn);
464
+ const baseName = info.name ?? info.type;
465
+ const spanName = `${baseName} attempt ${info.attempt}`;
466
+ // Find the parent Operation_Span for this operation
467
+ const parentSpan = this.spanMap.get(info.id);
468
+ const parentContext = parentSpan
469
+ ? api.trace.setSpan(api.context.active(), parentSpan)
470
+ : api.context.active();
471
+ // Get current trace ID for the link
472
+ const currentTraceId = this.invocationSpan?.spanContext().traceId ??
473
+ this.idGenerator.generateTraceId();
474
+ const attributes = {
475
+ "durable.execution.arn": this.executionArn,
476
+ "durable.operation.id": info.id,
477
+ "durable.operation.type": info.type,
478
+ "durable.operation.attempt": info.attempt,
479
+ };
480
+ if (info.name) {
481
+ attributes["durable.operation.name"] = info.name;
482
+ }
483
+ if (info.subType) {
484
+ attributes["durable.operation.subtype"] = info.subType;
485
+ }
486
+ // Create Attempt_Span as child of Operation_Span with Link to deterministic span
487
+ const attemptSpan = this.tracer.startSpan(spanName, {
488
+ attributes,
489
+ startTime: info.startTimestamp,
490
+ links: [
491
+ {
492
+ context: {
493
+ traceId: currentTraceId,
494
+ spanId: deterministicSpanId,
495
+ traceFlags: 1,
496
+ },
497
+ },
498
+ ],
499
+ }, parentContext);
500
+ this.attemptSpan = attemptSpan;
501
+ }
502
+ wrapOperationAttemptFn(_info, fn) {
503
+ if (!this.attemptSpan) {
504
+ return fn();
505
+ }
506
+ return api.context.with(api.trace.setSpan(api.context.active(), this.attemptSpan), fn);
507
+ }
508
+ async onOperationAttemptEnd(info) {
509
+ if (this.attemptSpan) {
510
+ this.attemptSpan.setAttribute("durable.attempt.outcome", info.outcome);
511
+ if (info.error) {
512
+ this.attemptSpan.setStatus({
513
+ code: api.SpanStatusCode.ERROR,
514
+ message: info.error.message,
515
+ });
516
+ this.attemptSpan.recordException(info.error);
517
+ }
518
+ this.attemptSpan.end(info.endTimestamp);
519
+ this.attemptSpan = undefined;
520
+ }
521
+ }
522
+ async onOperationChange(_info) {
523
+ // No-op for this plugin
524
+ }
525
+ enrichLogContext() {
526
+ const span = api.trace.getSpan(api.context.active());
527
+ if (!span) {
528
+ return undefined;
529
+ }
530
+ const spanContext = span.spanContext();
531
+ return {
532
+ traceId: spanContext.traceId,
533
+ spanId: spanContext.spanId,
534
+ otelTraceSampled: (spanContext.traceFlags & 1) !== 0,
535
+ };
536
+ }
537
+ }
538
+
539
+ exports.DeterministicIdGenerator = DeterministicIdGenerator;
540
+ exports.OtelPlugin = OtelPlugin;
541
+ exports.deriveSpanIdFromOperationId = deriveSpanIdFromOperationId;
542
+ exports.deriveTraceIdFromArn = deriveTraceIdFromArn;
543
+ exports.deriveTraceIdFromXRayRoot = deriveTraceIdFromXRayRoot;
544
+ exports.w3cClientContextExtractor = w3cClientContextExtractor;
545
+ exports.xRayContextExtractor = xRayContextExtractor;
546
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/deterministic-id-generator.ts","../src/context-extractors.ts","../src/plugin.ts"],"names":["createHash","trace","registerInstrumentations","AwsInstrumentation","context","SpanStatusCode"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { InvocationInfo } from "@aws/durable-execution-sdk-js";
2
+ /**
3
+ * Result type returned by context extractors.
4
+ */
5
+ export type ContextExtractorResult = {
6
+ traceId: string;
7
+ parentSpanId?: string;
8
+ traceFlags?: number;
9
+ } | undefined;
10
+ /**
11
+ * A function that extracts upstream trace context from the invocation environment.
12
+ */
13
+ export type ContextExtractor = (info: InvocationInfo) => ContextExtractorResult;
14
+ /**
15
+ * Reads the X-Ray trace header from the `_X_AMZN_TRACE_ID` environment variable.
16
+ *
17
+ * The durable execution backend propagates the same Root trace ID to every
18
+ * invocation, so all invocations of the same execution share one traceId.
19
+ *
20
+ * X-Ray Header format:
21
+ * Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1
22
+ *
23
+ * - Extract Root value, strip "1-" prefix and all "-" to get 32-char hex traceId
24
+ * - Extract Parent value for parentSpanId (16-char hex)
25
+ *
26
+ * Returns undefined when _X_AMZN_TRACE_ID is missing or malformed.
27
+ */
28
+ export declare function xRayContextExtractor(_info: InvocationInfo): ContextExtractorResult;
29
+ /**
30
+ * Reads W3C traceparent from `context.clientContext.custom.traceparent`.
31
+ *
32
+ * W3C traceparent format:
33
+ * 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
34
+ * Format: version-traceId-parentId-traceFlags
35
+ *
36
+ * - traceId is 32 hex chars
37
+ * - parentId is 16 hex chars
38
+ * - flags is 2 hex chars (parsed to number)
39
+ *
40
+ * Returns undefined when clientContext or traceparent is missing or malformed.
41
+ */
42
+ export declare function w3cClientContextExtractor(info: InvocationInfo): ContextExtractorResult;
43
+ //# sourceMappingURL=context-extractors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-extractors.d.ts","sourceRoot":"","sources":["../src/context-extractors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAC9B;IACE,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACD,SAAS,CAAC;AAEd;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,cAAc,KAAK,sBAAsB,CAAC;AAEhF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,cAAc,GACpB,sBAAsB,CAuCxB;AAeD;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,cAAc,GACnB,sBAAsB,CASxB"}
@@ -0,0 +1,70 @@
1
+ import type { IdGenerator } from "@opentelemetry/sdk-trace-node";
2
+ /**
3
+ * A custom OpenTelemetry IdGenerator that produces deterministic trace and span IDs
4
+ * derived from execution metadata (X-Ray headers, execution ARNs, operation IDs)
5
+ * rather than random values.
6
+ *
7
+ * This ensures that spans from different Lambda invocations of the same durable
8
+ * execution are stitched into a single coherent trace.
9
+ */
10
+ export declare class DeterministicIdGenerator implements IdGenerator {
11
+ private traceId;
12
+ private nextSpanId;
13
+ /**
14
+ * Set the trace ID for all subsequent generateTraceId() calls.
15
+ * This is persistent until setTraceId is called again.
16
+ */
17
+ setTraceId(traceId: string): void;
18
+ /**
19
+ * Set the span ID to return on the next single generateSpanId() call.
20
+ * This is a one-shot override: it is consumed on the next call and then
21
+ * reverts to default behavior.
22
+ */
23
+ setNextSpanId(spanId: string): void;
24
+ /**
25
+ * Generate a 32-char lowercase hex trace ID.
26
+ *
27
+ * If setTraceId has been called, returns that value persistently.
28
+ * Otherwise returns a random 32-char hex string as fallback.
29
+ */
30
+ generateTraceId(): string;
31
+ /**
32
+ * Generate a 16-char lowercase hex span ID.
33
+ *
34
+ * If setNextSpanId has been called, returns that value once (one-shot)
35
+ * and then clears it. Otherwise returns a random 16-char hex string.
36
+ */
37
+ generateSpanId(): string;
38
+ }
39
+ /**
40
+ * Derive a deterministic trace ID from an X-Ray Root field.
41
+ * Strips the `Root=1-` prefix and all `-` separators to produce
42
+ * a valid 32-character lowercase hex OpenTelemetry trace ID.
43
+ *
44
+ * @param xRayRoot - The Root field value, e.g. "1-5759e988-bd862e3fe1be46a994272793"
45
+ * @returns A 32-char lowercase hex string, or undefined if the input is invalid
46
+ */
47
+ export declare function deriveTraceIdFromXRayRoot(xRayRoot: string): string | undefined;
48
+ /**
49
+ * Derive a deterministic trace ID from an execution ARN by hashing it
50
+ * with SHA-256 and truncating to the first 32 lowercase hex characters.
51
+ *
52
+ * @param executionArn - The execution ARN string
53
+ * @returns A 32-char lowercase hex string
54
+ */
55
+ export declare function deriveTraceIdFromArn(executionArn: string): string;
56
+ /**
57
+ * Derive a deterministic span ID from an operation ID scoped to a specific execution.
58
+ * Hashes `executionArn + ":" + operationId` with SHA-256 and truncates to the first
59
+ * 16 lowercase hex characters.
60
+ *
61
+ * The executionArn is included in the hash input to avoid span ID collisions when
62
+ * different executions (e.g., a parent and child workflow) share the same trace and
63
+ * have operations at the same positional ID.
64
+ *
65
+ * @param operationId - The operation ID string (positional identifier within an execution)
66
+ * @param executionArn - The execution ARN, used to scope span IDs per execution
67
+ * @returns A 16-char lowercase hex string
68
+ */
69
+ export declare function deriveSpanIdFromOperationId(operationId: string, executionArn: string): string;
70
+ //# sourceMappingURL=deterministic-id-generator.d.ts.map