autotel-aws 0.2.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.
- package/LICENSE +21 -0
- package/README.md +540 -0
- package/dist/attributes.cjs +49 -0
- package/dist/attributes.cjs.map +1 -0
- package/dist/attributes.d.cts +117 -0
- package/dist/attributes.d.ts +117 -0
- package/dist/attributes.js +4 -0
- package/dist/attributes.js.map +1 -0
- package/dist/chunk-35F3UBOO.cjs +48 -0
- package/dist/chunk-35F3UBOO.cjs.map +1 -0
- package/dist/chunk-4TGVGEUN.cjs +84 -0
- package/dist/chunk-4TGVGEUN.cjs.map +1 -0
- package/dist/chunk-CIGXV6HA.js +192 -0
- package/dist/chunk-CIGXV6HA.js.map +1 -0
- package/dist/chunk-D5INYMRP.cjs +350 -0
- package/dist/chunk-D5INYMRP.cjs.map +1 -0
- package/dist/chunk-DF5PT3JK.js +387 -0
- package/dist/chunk-DF5PT3JK.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +10 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-DHHLKZHI.cjs +23 -0
- package/dist/chunk-DHHLKZHI.cjs.map +1 -0
- package/dist/chunk-FKZOELBT.js +78 -0
- package/dist/chunk-FKZOELBT.js.map +1 -0
- package/dist/chunk-HMTKKKKP.cjs +390 -0
- package/dist/chunk-HMTKKKKP.cjs.map +1 -0
- package/dist/chunk-I4CKQ4RD.js +153 -0
- package/dist/chunk-I4CKQ4RD.js.map +1 -0
- package/dist/chunk-JEQ2X3Z6.cjs +12 -0
- package/dist/chunk-JEQ2X3Z6.cjs.map +1 -0
- package/dist/chunk-JMSFE6FJ.js +24 -0
- package/dist/chunk-JMSFE6FJ.js.map +1 -0
- package/dist/chunk-KUIOI74B.cjs +394 -0
- package/dist/chunk-KUIOI74B.cjs.map +1 -0
- package/dist/chunk-NQ65Y5AI.cjs +195 -0
- package/dist/chunk-NQ65Y5AI.cjs.map +1 -0
- package/dist/chunk-OB4XTAVK.cjs +345 -0
- package/dist/chunk-OB4XTAVK.cjs.map +1 -0
- package/dist/chunk-OHFR7WX5.js +341 -0
- package/dist/chunk-OHFR7WX5.js.map +1 -0
- package/dist/chunk-PZGYL7XZ.js +40 -0
- package/dist/chunk-PZGYL7XZ.js.map +1 -0
- package/dist/chunk-Q3DMMQ7K.cjs +164 -0
- package/dist/chunk-Q3DMMQ7K.cjs.map +1 -0
- package/dist/chunk-UZEJV2YD.cjs +139 -0
- package/dist/chunk-UZEJV2YD.cjs.map +1 -0
- package/dist/chunk-V4IQWFYN.js +341 -0
- package/dist/chunk-V4IQWFYN.js.map +1 -0
- package/dist/chunk-VZHQH75L.cjs +26 -0
- package/dist/chunk-VZHQH75L.cjs.map +1 -0
- package/dist/chunk-X6BY6PCK.js +386 -0
- package/dist/chunk-X6BY6PCK.js.map +1 -0
- package/dist/chunk-YG56NRIO.js +131 -0
- package/dist/chunk-YG56NRIO.js.map +1 -0
- package/dist/chunk-ZPDRKCAR.js +21 -0
- package/dist/chunk-ZPDRKCAR.js.map +1 -0
- package/dist/config-C7zV8Zm6.d.cts +125 -0
- package/dist/config-DxjTT8jd.d.ts +125 -0
- package/dist/dynamodb.cjs +14 -0
- package/dist/dynamodb.cjs.map +1 -0
- package/dist/dynamodb.d.cts +93 -0
- package/dist/dynamodb.d.ts +93 -0
- package/dist/dynamodb.js +5 -0
- package/dist/dynamodb.js.map +1 -0
- package/dist/eventbridge.cjs +279 -0
- package/dist/eventbridge.cjs.map +1 -0
- package/dist/eventbridge.d.cts +360 -0
- package/dist/eventbridge.d.ts +360 -0
- package/dist/eventbridge.js +273 -0
- package/dist/eventbridge.js.map +1 -0
- package/dist/index.cjs +251 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +126 -0
- package/dist/index.d.ts +126 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/kinesis.cjs +23 -0
- package/dist/kinesis.cjs.map +1 -0
- package/dist/kinesis.d.cts +360 -0
- package/dist/kinesis.d.ts +360 -0
- package/dist/kinesis.js +6 -0
- package/dist/kinesis.js.map +1 -0
- package/dist/lambda-auto.cjs +19 -0
- package/dist/lambda-auto.cjs.map +1 -0
- package/dist/lambda-auto.d.cts +2 -0
- package/dist/lambda-auto.d.ts +2 -0
- package/dist/lambda-auto.js +17 -0
- package/dist/lambda-auto.js.map +1 -0
- package/dist/lambda.cjs +42 -0
- package/dist/lambda.cjs.map +1 -0
- package/dist/lambda.d.cts +231 -0
- package/dist/lambda.d.ts +231 -0
- package/dist/lambda.js +5 -0
- package/dist/lambda.js.map +1 -0
- package/dist/s3.cjs +14 -0
- package/dist/s3.cjs.map +1 -0
- package/dist/s3.d.cts +77 -0
- package/dist/s3.d.ts +77 -0
- package/dist/s3.js +5 -0
- package/dist/s3.js.map +1 -0
- package/dist/sdk.cjs +31 -0
- package/dist/sdk.cjs.map +1 -0
- package/dist/sdk.d.cts +155 -0
- package/dist/sdk.d.ts +155 -0
- package/dist/sdk.js +6 -0
- package/dist/sdk.js.map +1 -0
- package/dist/sns.cjs +19 -0
- package/dist/sns.cjs.map +1 -0
- package/dist/sns.d.cts +256 -0
- package/dist/sns.d.ts +256 -0
- package/dist/sns.js +6 -0
- package/dist/sns.js.map +1 -0
- package/dist/sqs.cjs +23 -0
- package/dist/sqs.cjs.map +1 -0
- package/dist/sqs.d.cts +384 -0
- package/dist/sqs.d.ts +384 -0
- package/dist/sqs.js +6 -0
- package/dist/sqs.js.map +1 -0
- package/dist/step-functions.cjs +35 -0
- package/dist/step-functions.cjs.map +1 -0
- package/dist/step-functions.d.cts +423 -0
- package/dist/step-functions.d.ts +423 -0
- package/dist/step-functions.js +6 -0
- package/dist/step-functions.js.map +1 -0
- package/dist/testing.cjs +61 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +39 -0
- package/dist/testing.d.ts +39 -0
- package/dist/testing.js +58 -0
- package/dist/testing.js.map +1 -0
- package/dist/types-3_ak5jhy.d.cts +76 -0
- package/dist/types-3_ak5jhy.d.ts +76 -0
- package/dist/types-UiBv_I_M.d.ts +16 -0
- package/dist/types-kTFVdSqO.d.cts +16 -0
- package/dist/xray.cjs +26 -0
- package/dist/xray.cjs.map +1 -0
- package/dist/xray.d.cts +23 -0
- package/dist/xray.d.ts +23 -0
- package/dist/xray.js +5 -0
- package/dist/xray.js.map +1 -0
- package/package.json +184 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import { wrapSDKClient } from './chunk-YG56NRIO.js';
|
|
2
|
+
import { buildStepFunctionsAttributes } from './chunk-I4CKQ4RD.js';
|
|
3
|
+
import { trace } from 'autotel';
|
|
4
|
+
import { propagation, context, SpanStatusCode } from '@opentelemetry/api';
|
|
5
|
+
|
|
6
|
+
function injectTraceContext(input) {
|
|
7
|
+
const carrier = {};
|
|
8
|
+
propagation.inject(context.active(), carrier);
|
|
9
|
+
if (!carrier.traceparent) {
|
|
10
|
+
return input;
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
...input,
|
|
14
|
+
_traceContext: {
|
|
15
|
+
traceparent: carrier.traceparent,
|
|
16
|
+
...carrier.tracestate && { tracestate: carrier.tracestate },
|
|
17
|
+
...carrier.baggage && { baggage: carrier.baggage }
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function extractStepFunctionsContext(input) {
|
|
22
|
+
if (typeof input !== "object" || input === null || !("_traceContext" in input)) {
|
|
23
|
+
return void 0;
|
|
24
|
+
}
|
|
25
|
+
const traceContext = input._traceContext;
|
|
26
|
+
if (!traceContext?.traceparent) {
|
|
27
|
+
return void 0;
|
|
28
|
+
}
|
|
29
|
+
const carrier = {
|
|
30
|
+
traceparent: traceContext.traceparent,
|
|
31
|
+
...traceContext.tracestate && { tracestate: traceContext.tracestate },
|
|
32
|
+
...traceContext.baggage && { baggage: traceContext.baggage }
|
|
33
|
+
};
|
|
34
|
+
const extractedContext = propagation.extract(context.active(), carrier);
|
|
35
|
+
const span = extractedContext.getValue(Symbol.for("OpenTelemetry Context Key SPAN"));
|
|
36
|
+
if (span && typeof span === "object") {
|
|
37
|
+
if ("spanContext" in span && typeof span.spanContext === "function") {
|
|
38
|
+
return span.spanContext();
|
|
39
|
+
}
|
|
40
|
+
if ("traceId" in span && "spanId" in span) {
|
|
41
|
+
return span;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return void 0;
|
|
45
|
+
}
|
|
46
|
+
function stripTraceContext(input) {
|
|
47
|
+
const { _traceContext: _, ...rest } = input;
|
|
48
|
+
return rest;
|
|
49
|
+
}
|
|
50
|
+
function traceStepFunction(config) {
|
|
51
|
+
const operation = config.operation ?? "execute";
|
|
52
|
+
return function wrapper(fn) {
|
|
53
|
+
return trace(
|
|
54
|
+
`stepfunctions.${operation}`,
|
|
55
|
+
(ctx) => async (...args) => {
|
|
56
|
+
ctx.setAttributes(
|
|
57
|
+
buildStepFunctionsAttributes({
|
|
58
|
+
stateMachineArn: config.stateMachineArn
|
|
59
|
+
})
|
|
60
|
+
);
|
|
61
|
+
const handler = fn(ctx);
|
|
62
|
+
return handler(...args);
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
var StepFunctionsExecutor = class {
|
|
68
|
+
client;
|
|
69
|
+
config;
|
|
70
|
+
stateMachineName;
|
|
71
|
+
constructor(client, config) {
|
|
72
|
+
this.client = wrapSDKClient(client, config.service);
|
|
73
|
+
this.config = {
|
|
74
|
+
injectTraceContext: true,
|
|
75
|
+
...config
|
|
76
|
+
};
|
|
77
|
+
this.stateMachineName = config.stateMachineArn.split(":").pop() || "unknown";
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Start a new execution of the state machine
|
|
81
|
+
*
|
|
82
|
+
* @param execution - Execution input and optional name
|
|
83
|
+
* @returns Promise with execution ARN and start date
|
|
84
|
+
*/
|
|
85
|
+
async startExecution(execution) {
|
|
86
|
+
return trace(`stepfunctions.StartExecution`, async (ctx) => {
|
|
87
|
+
ctx.setAttributes(
|
|
88
|
+
buildStepFunctionsAttributes({
|
|
89
|
+
stateMachineArn: this.config.stateMachineArn
|
|
90
|
+
})
|
|
91
|
+
);
|
|
92
|
+
ctx.setAttribute("aws.stepfunctions.state_machine_name", this.stateMachineName);
|
|
93
|
+
if (execution.name) {
|
|
94
|
+
ctx.setAttribute("aws.stepfunctions.execution_name", execution.name);
|
|
95
|
+
}
|
|
96
|
+
const inputData = this.config.injectTraceContext ? injectTraceContext(execution.input) : execution.input;
|
|
97
|
+
const input = {
|
|
98
|
+
stateMachineArn: this.config.stateMachineArn,
|
|
99
|
+
input: JSON.stringify(inputData),
|
|
100
|
+
name: execution.name,
|
|
101
|
+
traceHeader: execution.traceHeader
|
|
102
|
+
};
|
|
103
|
+
try {
|
|
104
|
+
const { StartExecutionCommand } = await import('@aws-sdk/client-sfn');
|
|
105
|
+
const result = await this.client.send(new StartExecutionCommand(input));
|
|
106
|
+
if (result.executionArn) {
|
|
107
|
+
ctx.setAttribute("aws.stepfunctions.execution_arn", result.executionArn);
|
|
108
|
+
}
|
|
109
|
+
ctx.setStatus({ code: SpanStatusCode.OK });
|
|
110
|
+
return {
|
|
111
|
+
executionArn: result.executionArn,
|
|
112
|
+
startDate: result.startDate
|
|
113
|
+
};
|
|
114
|
+
} catch (error) {
|
|
115
|
+
ctx.setStatus({
|
|
116
|
+
code: SpanStatusCode.ERROR,
|
|
117
|
+
message: error instanceof Error ? error.message : "StartExecution failed"
|
|
118
|
+
});
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Start a synchronous execution (Express workflows only)
|
|
125
|
+
*
|
|
126
|
+
* @param execution - Execution input and optional name
|
|
127
|
+
* @returns Promise with execution result including output
|
|
128
|
+
*/
|
|
129
|
+
async startSyncExecution(execution) {
|
|
130
|
+
return trace(`stepfunctions.StartSyncExecution`, async (ctx) => {
|
|
131
|
+
ctx.setAttributes(
|
|
132
|
+
buildStepFunctionsAttributes({
|
|
133
|
+
stateMachineArn: this.config.stateMachineArn
|
|
134
|
+
})
|
|
135
|
+
);
|
|
136
|
+
ctx.setAttribute("aws.stepfunctions.state_machine_name", this.stateMachineName);
|
|
137
|
+
ctx.setAttribute("aws.stepfunctions.execution_type", "express");
|
|
138
|
+
if (execution.name) {
|
|
139
|
+
ctx.setAttribute("aws.stepfunctions.execution_name", execution.name);
|
|
140
|
+
}
|
|
141
|
+
const inputData = this.config.injectTraceContext ? injectTraceContext(execution.input) : execution.input;
|
|
142
|
+
const input = {
|
|
143
|
+
stateMachineArn: this.config.stateMachineArn,
|
|
144
|
+
input: JSON.stringify(inputData),
|
|
145
|
+
name: execution.name,
|
|
146
|
+
traceHeader: execution.traceHeader
|
|
147
|
+
};
|
|
148
|
+
try {
|
|
149
|
+
const { StartSyncExecutionCommand } = await import('@aws-sdk/client-sfn');
|
|
150
|
+
const result = await this.client.send(new StartSyncExecutionCommand(input));
|
|
151
|
+
if (result.executionArn) {
|
|
152
|
+
ctx.setAttribute("aws.stepfunctions.execution_arn", result.executionArn);
|
|
153
|
+
}
|
|
154
|
+
if (result.status) {
|
|
155
|
+
ctx.setAttribute("aws.stepfunctions.execution_status", result.status);
|
|
156
|
+
}
|
|
157
|
+
if (result.status === "FAILED" || result.status === "TIMED_OUT") {
|
|
158
|
+
ctx.setStatus({
|
|
159
|
+
code: SpanStatusCode.ERROR,
|
|
160
|
+
message: result.error || result.status
|
|
161
|
+
});
|
|
162
|
+
} else {
|
|
163
|
+
ctx.setStatus({ code: SpanStatusCode.OK });
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
executionArn: result.executionArn,
|
|
167
|
+
status: result.status,
|
|
168
|
+
output: result.output,
|
|
169
|
+
error: result.error,
|
|
170
|
+
cause: result.cause,
|
|
171
|
+
billingDetails: result.billingDetails ? {
|
|
172
|
+
billedMemoryUsedInMB: result.billingDetails.billedMemoryUsedInMB,
|
|
173
|
+
billedDurationInMilliseconds: result.billingDetails.billedDurationInMilliseconds
|
|
174
|
+
} : void 0
|
|
175
|
+
};
|
|
176
|
+
} catch (error) {
|
|
177
|
+
ctx.setStatus({
|
|
178
|
+
code: SpanStatusCode.ERROR,
|
|
179
|
+
message: error instanceof Error ? error.message : "StartSyncExecution failed"
|
|
180
|
+
});
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Describe an execution
|
|
187
|
+
*
|
|
188
|
+
* @param executionArn - ARN of the execution to describe
|
|
189
|
+
* @returns Promise with execution details
|
|
190
|
+
*/
|
|
191
|
+
async describeExecution(executionArn) {
|
|
192
|
+
return trace(`stepfunctions.DescribeExecution`, async (ctx) => {
|
|
193
|
+
ctx.setAttributes(
|
|
194
|
+
buildStepFunctionsAttributes({
|
|
195
|
+
stateMachineArn: this.config.stateMachineArn
|
|
196
|
+
})
|
|
197
|
+
);
|
|
198
|
+
ctx.setAttribute("aws.stepfunctions.execution_arn", executionArn);
|
|
199
|
+
try {
|
|
200
|
+
const { DescribeExecutionCommand } = await import('@aws-sdk/client-sfn');
|
|
201
|
+
const result = await this.client.send(
|
|
202
|
+
new DescribeExecutionCommand({ executionArn })
|
|
203
|
+
);
|
|
204
|
+
if (result.status) {
|
|
205
|
+
ctx.setAttribute("aws.stepfunctions.execution_status", result.status);
|
|
206
|
+
}
|
|
207
|
+
ctx.setStatus({ code: SpanStatusCode.OK });
|
|
208
|
+
return {
|
|
209
|
+
executionArn: result.executionArn,
|
|
210
|
+
stateMachineArn: result.stateMachineArn,
|
|
211
|
+
name: result.name,
|
|
212
|
+
status: result.status,
|
|
213
|
+
startDate: result.startDate,
|
|
214
|
+
stopDate: result.stopDate,
|
|
215
|
+
input: result.input,
|
|
216
|
+
output: result.output,
|
|
217
|
+
error: result.error,
|
|
218
|
+
cause: result.cause
|
|
219
|
+
};
|
|
220
|
+
} catch (error) {
|
|
221
|
+
ctx.setStatus({
|
|
222
|
+
code: SpanStatusCode.ERROR,
|
|
223
|
+
message: error instanceof Error ? error.message : "DescribeExecution failed"
|
|
224
|
+
});
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Stop an execution
|
|
231
|
+
*
|
|
232
|
+
* @param executionArn - ARN of the execution to stop
|
|
233
|
+
* @param options - Optional error and cause for the stop
|
|
234
|
+
* @returns Promise with stop date
|
|
235
|
+
*/
|
|
236
|
+
async stopExecution(executionArn, options) {
|
|
237
|
+
return trace(`stepfunctions.StopExecution`, async (ctx) => {
|
|
238
|
+
ctx.setAttributes(
|
|
239
|
+
buildStepFunctionsAttributes({
|
|
240
|
+
stateMachineArn: this.config.stateMachineArn
|
|
241
|
+
})
|
|
242
|
+
);
|
|
243
|
+
ctx.setAttribute("aws.stepfunctions.execution_arn", executionArn);
|
|
244
|
+
try {
|
|
245
|
+
const { StopExecutionCommand } = await import('@aws-sdk/client-sfn');
|
|
246
|
+
const result = await this.client.send(
|
|
247
|
+
new StopExecutionCommand({
|
|
248
|
+
executionArn,
|
|
249
|
+
error: options?.error,
|
|
250
|
+
cause: options?.cause
|
|
251
|
+
})
|
|
252
|
+
);
|
|
253
|
+
ctx.setStatus({ code: SpanStatusCode.OK });
|
|
254
|
+
return { stopDate: result.stopDate };
|
|
255
|
+
} catch (error) {
|
|
256
|
+
ctx.setStatus({
|
|
257
|
+
code: SpanStatusCode.ERROR,
|
|
258
|
+
message: error instanceof Error ? error.message : "StopExecution failed"
|
|
259
|
+
});
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
var StepFunctionsActivityWorker = class {
|
|
266
|
+
client;
|
|
267
|
+
config;
|
|
268
|
+
activityName;
|
|
269
|
+
constructor(client, config) {
|
|
270
|
+
this.client = wrapSDKClient(client, config.service);
|
|
271
|
+
this.config = {
|
|
272
|
+
extractTraceContext: true,
|
|
273
|
+
...config
|
|
274
|
+
};
|
|
275
|
+
this.activityName = config.activityArn.split(":").pop() || "unknown";
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Poll for an activity task and process it
|
|
279
|
+
*
|
|
280
|
+
* @param processor - Function to process the task input
|
|
281
|
+
* @returns Promise that resolves when the task is processed
|
|
282
|
+
*/
|
|
283
|
+
async poll(processor) {
|
|
284
|
+
return trace(`stepfunctions.activity.poll`, async (ctx) => {
|
|
285
|
+
ctx.setAttribute("aws.stepfunctions.activity_arn", this.config.activityArn);
|
|
286
|
+
ctx.setAttribute("aws.stepfunctions.activity_name", this.activityName);
|
|
287
|
+
if (this.config.workerName) {
|
|
288
|
+
ctx.setAttribute("aws.stepfunctions.worker_name", this.config.workerName);
|
|
289
|
+
}
|
|
290
|
+
try {
|
|
291
|
+
const { GetActivityTaskCommand } = await import('@aws-sdk/client-sfn');
|
|
292
|
+
const task = await this.client.send(
|
|
293
|
+
new GetActivityTaskCommand({
|
|
294
|
+
activityArn: this.config.activityArn,
|
|
295
|
+
workerName: this.config.workerName
|
|
296
|
+
})
|
|
297
|
+
);
|
|
298
|
+
if (!task.taskToken || !task.input) {
|
|
299
|
+
ctx.setAttribute("aws.stepfunctions.activity_task_received", false);
|
|
300
|
+
ctx.setStatus({ code: SpanStatusCode.OK });
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
ctx.setAttribute("aws.stepfunctions.activity_task_received", true);
|
|
304
|
+
const rawInput = JSON.parse(task.input);
|
|
305
|
+
if (this.config.extractTraceContext) {
|
|
306
|
+
const parentContext = extractStepFunctionsContext(rawInput);
|
|
307
|
+
if (parentContext) {
|
|
308
|
+
ctx.setAttribute("aws.stepfunctions.trace_context_extracted", true);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const cleanInput = stripTraceContext(rawInput);
|
|
312
|
+
const output = await processor(cleanInput, task.taskToken, ctx);
|
|
313
|
+
const { SendTaskSuccessCommand } = await import('@aws-sdk/client-sfn');
|
|
314
|
+
await this.client.send(
|
|
315
|
+
new SendTaskSuccessCommand({
|
|
316
|
+
taskToken: task.taskToken,
|
|
317
|
+
output: JSON.stringify(output)
|
|
318
|
+
})
|
|
319
|
+
);
|
|
320
|
+
ctx.setStatus({ code: SpanStatusCode.OK });
|
|
321
|
+
} catch (error) {
|
|
322
|
+
ctx.setStatus({
|
|
323
|
+
code: SpanStatusCode.ERROR,
|
|
324
|
+
message: error instanceof Error ? error.message : "Activity processing failed"
|
|
325
|
+
});
|
|
326
|
+
throw error;
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Send a task heartbeat
|
|
332
|
+
*
|
|
333
|
+
* For long-running activities, send heartbeats to prevent timeout.
|
|
334
|
+
*
|
|
335
|
+
* @param taskToken - The task token from GetActivityTask
|
|
336
|
+
*/
|
|
337
|
+
async sendHeartbeat(taskToken) {
|
|
338
|
+
return trace(`stepfunctions.SendTaskHeartbeat`, async (ctx) => {
|
|
339
|
+
ctx.setAttribute("aws.stepfunctions.activity_arn", this.config.activityArn);
|
|
340
|
+
try {
|
|
341
|
+
const { SendTaskHeartbeatCommand } = await import('@aws-sdk/client-sfn');
|
|
342
|
+
await this.client.send(new SendTaskHeartbeatCommand({ taskToken }));
|
|
343
|
+
ctx.setStatus({ code: SpanStatusCode.OK });
|
|
344
|
+
} catch (error) {
|
|
345
|
+
ctx.setStatus({
|
|
346
|
+
code: SpanStatusCode.ERROR,
|
|
347
|
+
message: error instanceof Error ? error.message : "SendTaskHeartbeat failed"
|
|
348
|
+
});
|
|
349
|
+
throw error;
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Send task failure
|
|
355
|
+
*
|
|
356
|
+
* @param taskToken - The task token from GetActivityTask
|
|
357
|
+
* @param error - Error code
|
|
358
|
+
* @param cause - Error cause description
|
|
359
|
+
*/
|
|
360
|
+
async sendFailure(taskToken, error, cause) {
|
|
361
|
+
return trace(`stepfunctions.SendTaskFailure`, async (ctx) => {
|
|
362
|
+
ctx.setAttribute("aws.stepfunctions.activity_arn", this.config.activityArn);
|
|
363
|
+
ctx.setAttribute("aws.stepfunctions.task_error", error);
|
|
364
|
+
try {
|
|
365
|
+
const { SendTaskFailureCommand } = await import('@aws-sdk/client-sfn');
|
|
366
|
+
await this.client.send(
|
|
367
|
+
new SendTaskFailureCommand({
|
|
368
|
+
taskToken,
|
|
369
|
+
error,
|
|
370
|
+
cause
|
|
371
|
+
})
|
|
372
|
+
);
|
|
373
|
+
ctx.setStatus({ code: SpanStatusCode.OK });
|
|
374
|
+
} catch (error_) {
|
|
375
|
+
ctx.setStatus({
|
|
376
|
+
code: SpanStatusCode.ERROR,
|
|
377
|
+
message: error_ instanceof Error ? error_.message : "SendTaskFailure failed"
|
|
378
|
+
});
|
|
379
|
+
throw error_;
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
export { StepFunctionsActivityWorker, StepFunctionsExecutor, extractStepFunctionsContext, injectTraceContext, stripTraceContext, traceStepFunction };
|
|
386
|
+
//# sourceMappingURL=chunk-DF5PT3JK.js.map
|
|
387
|
+
//# sourceMappingURL=chunk-DF5PT3JK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/step-functions/index.ts"],"names":[],"mappings":"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","file":"chunk-DF5PT3JK.js","sourcesContent":["/**\n * Step Functions instrumentation\n *\n * Provides semantic helpers for tracing AWS Step Functions operations\n * with context propagation for distributed tracing across state machines.\n *\n * @example Start workflow with trace context\n * ```typescript\n * import { StepFunctionsExecutor, injectTraceContext } from 'autotel-aws/step-functions';\n * import { SFNClient } from '@aws-sdk/client-sfn';\n *\n * const sfn = new SFNClient({});\n * const executor = new StepFunctionsExecutor(sfn, {\n * stateMachineArn: 'arn:aws:states:us-east-1:123456789:stateMachine:OrderProcessor'\n * });\n *\n * // Start execution with automatic trace context injection\n * const result = await executor.startExecution({\n * input: { orderId: '123', items: [...] },\n * name: 'order-123-execution'\n * });\n * ```\n *\n * @example Extract context in Lambda invoked by Step Functions\n * ```typescript\n * import { extractStepFunctionsContext } from 'autotel-aws/step-functions';\n * import { wrapHandler } from 'autotel-aws/lambda';\n *\n * export const handler = wrapHandler(async (event) => {\n * // Extract trace context from Step Functions input\n * const parentContext = extractStepFunctionsContext(event);\n *\n * // Process the order (without the trace context fields)\n * const { orderId, items } = event;\n * await processOrder(orderId, items);\n *\n * return { status: 'completed' };\n * });\n * ```\n *\n * @example Activity worker with context propagation\n * ```typescript\n * import { StepFunctionsActivityWorker } from 'autotel-aws/step-functions';\n *\n * const worker = new StepFunctionsActivityWorker(sfn, {\n * activityArn: 'arn:aws:states:us-east-1:123456789:activity:ProcessPayment'\n * });\n *\n * // Worker extracts trace context and creates child spans\n * await worker.poll(async (input, taskToken, ctx) => {\n * ctx.setAttribute('payment.amount', input.amount);\n * const result = await processPayment(input);\n * return result;\n * });\n * ```\n */\n\nimport { trace, type TraceContext } from 'autotel';\nimport { context, propagation, SpanStatusCode } from '@opentelemetry/api';\nimport type { SpanContext } from '@opentelemetry/api';\nimport { buildStepFunctionsAttributes } from '../attributes';\nimport { wrapSDKClient } from '../common/sdk-wrapper';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Step Functions operation configuration\n */\nexport interface TraceStepFunctionConfig {\n /**\n * State machine ARN\n * Sets `aws.stepfunctions.state_machine_arn` attribute.\n */\n stateMachineArn: string;\n\n /**\n * Operation type\n * Used to generate the span name: `stepfunctions.{operation}`\n * @default 'execute'\n */\n operation?:\n | 'StartExecution'\n | 'DescribeExecution'\n | 'StopExecution'\n | 'ListExecutions'\n | 'SendTaskSuccess'\n | 'SendTaskFailure'\n | 'execute'; // Legacy alias for StartExecution\n}\n\n/**\n * Configuration for StepFunctionsExecutor\n */\nexport interface StepFunctionsExecutorConfig {\n /**\n * State machine ARN\n */\n stateMachineArn: string;\n\n /**\n * Inject W3C Trace Context into execution input\n * @default true\n */\n injectTraceContext?: boolean;\n\n /**\n * Optional service name for tracing\n */\n service?: string;\n}\n\n/**\n * Execution input with optional trace context\n */\nexport interface ExecutionInput<T = Record<string, unknown>> {\n /**\n * The input data for the execution\n */\n input: T;\n\n /**\n * Optional execution name (must be unique within 90 days)\n */\n name?: string;\n\n /**\n * Optional trace ID for idempotency\n */\n traceHeader?: string;\n}\n\n/**\n * Configuration for StepFunctionsActivityWorker\n */\nexport interface StepFunctionsActivityWorkerConfig {\n /**\n * Activity ARN\n */\n activityArn: string;\n\n /**\n * Worker name for identification\n */\n workerName?: string;\n\n /**\n * Extract trace context from activity input\n * @default true\n */\n extractTraceContext?: boolean;\n\n /**\n * Optional service name for tracing\n */\n service?: string;\n}\n\n/**\n * Trace context fields injected into Step Functions input\n */\ninterface TraceContextFields {\n _traceContext?: {\n traceparent: string;\n tracestate?: string;\n baggage?: string;\n };\n}\n\n// ============================================================================\n// Context Propagation Helpers\n// ============================================================================\n\n/**\n * Inject W3C Trace Context into Step Functions execution input\n *\n * Adds `_traceContext` field with traceparent, tracestate, and baggage.\n * This enables distributed tracing across Step Functions executions\n * and Lambda functions invoked by the state machine.\n *\n * @param input - The original execution input\n * @returns Input with trace context injected\n *\n * @example\n * ```typescript\n * const input = { orderId: '123', items: [...] };\n * const inputWithContext = injectTraceContext(input);\n * // { orderId: '123', items: [...], _traceContext: { traceparent: '...' } }\n *\n * await sfn.send(new StartExecutionCommand({\n * stateMachineArn: 'arn:...',\n * input: JSON.stringify(inputWithContext)\n * }));\n * ```\n */\nexport function injectTraceContext<T extends Record<string, unknown>>(\n input: T,\n): T & TraceContextFields {\n const carrier: Record<string, string> = {};\n propagation.inject(context.active(), carrier);\n\n if (!carrier.traceparent) {\n return input;\n }\n\n return {\n ...input,\n _traceContext: {\n traceparent: carrier.traceparent,\n ...(carrier.tracestate && { tracestate: carrier.tracestate }),\n ...(carrier.baggage && { baggage: carrier.baggage }),\n },\n };\n}\n\n/**\n * Extract W3C Trace Context from Step Functions input\n *\n * Extracts the `_traceContext` field added by injectTraceContext.\n * Returns the SpanContext if present, or undefined.\n *\n * @param input - Step Functions input (event in Lambda handler)\n * @returns SpanContext if trace context was found, undefined otherwise\n *\n * @example\n * ```typescript\n * // In a Lambda invoked by Step Functions\n * export const handler = async (event) => {\n * const parentContext = extractStepFunctionsContext(event);\n * // Use parentContext to link traces...\n *\n * // Access data without trace context\n * const { orderId, items } = stripTraceContext(event);\n * };\n * ```\n */\nexport function extractStepFunctionsContext(\n input: unknown,\n): SpanContext | undefined {\n if (\n typeof input !== 'object' ||\n input === null ||\n !('_traceContext' in input)\n ) {\n return undefined;\n }\n\n const traceContext = (input as TraceContextFields)._traceContext;\n if (!traceContext?.traceparent) {\n return undefined;\n }\n\n // Use W3C Trace Context propagator to extract\n const carrier: Record<string, string> = {\n traceparent: traceContext.traceparent,\n ...(traceContext.tracestate && { tracestate: traceContext.tracestate }),\n ...(traceContext.baggage && { baggage: traceContext.baggage }),\n };\n\n const extractedContext = propagation.extract(context.active(), carrier);\n const span = extractedContext.getValue(Symbol.for('OpenTelemetry Context Key SPAN'));\n\n // Handle both Span and SpanContext\n if (span && typeof span === 'object') {\n if ('spanContext' in span && typeof span.spanContext === 'function') {\n return span.spanContext() as SpanContext;\n }\n // Might already be a SpanContext\n if ('traceId' in span && 'spanId' in span) {\n return span as SpanContext;\n }\n }\n\n return undefined;\n}\n\n/**\n * Strip trace context fields from Step Functions input\n *\n * Returns the input without `_traceContext` field for cleaner processing.\n *\n * @param input - Step Functions input with optional trace context\n * @returns Input without trace context fields\n *\n * @example\n * ```typescript\n * const event = { orderId: '123', _traceContext: { ... } };\n * const cleanInput = stripTraceContext(event);\n * // { orderId: '123' }\n * ```\n */\nexport function stripTraceContext<T extends Record<string, unknown>>(\n input: T,\n): Omit<T, '_traceContext'> {\n const { _traceContext: _, ...rest } = input as T & TraceContextFields;\n return rest as Omit<T, '_traceContext'>;\n}\n\n// ============================================================================\n// Trace Helper (Original API)\n// ============================================================================\n\n/**\n * Trace Step Functions operations\n *\n * Creates a traced function that automatically sets Step Functions attributes.\n *\n * @param config - Step Functions operation configuration\n * @returns A higher-order function that wraps your Step Functions operation with tracing\n *\n * @remarks\n * Semantic attributes set automatically:\n * - `aws.stepfunctions.state_machine_arn` - State machine ARN\n *\n * Additional attributes you should set in your handler:\n * - `aws.stepfunctions.execution_arn` - Execution ARN\n * - `aws.stepfunctions.execution_name` - Execution name\n *\n * @example\n * ```typescript\n * export const startWorkflow = traceStepFunction({\n * stateMachineArn: 'arn:aws:states:us-east-1:123456789:stateMachine:OrderProcessor',\n * operation: 'StartExecution'\n * })(ctx => async (input: object, executionName?: string) => {\n * const result = await sfn.send(new StartExecutionCommand({\n * stateMachineArn: 'arn:aws:states:...',\n * input: JSON.stringify(injectTraceContext(input)),\n * name: executionName\n * }));\n *\n * ctx.setAttribute('aws.stepfunctions.execution_arn', result.executionArn ?? '');\n * return result;\n * });\n * ```\n */\nexport function traceStepFunction(config: TraceStepFunctionConfig) {\n const operation = config.operation ?? 'execute';\n\n return function wrapper<TArgs extends unknown[], TReturn>(\n fn: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): (...args: TArgs) => Promise<TReturn> {\n // Use autotel's trace() which properly handles the factory pattern\n return trace(\n `stepfunctions.${operation}`,\n (ctx: TraceContext) =>\n async (...args: TArgs): Promise<TReturn> => {\n // Set Step Functions attributes\n ctx.setAttributes(\n buildStepFunctionsAttributes({\n stateMachineArn: config.stateMachineArn,\n }),\n );\n\n // Get the user's handler and execute with forwarded arguments\n const handler = fn(ctx);\n return handler(...args);\n },\n );\n };\n}\n\n// ============================================================================\n// StepFunctionsExecutor Class\n// ============================================================================\n\n/**\n * Step Functions Executor with automatic trace context injection\n *\n * Wraps an SFN client to automatically:\n * - Create spans for all operations\n * - Inject W3C Trace Context into execution input\n * - Set proper semantic attributes\n *\n * @example Basic usage\n * ```typescript\n * import { StepFunctionsExecutor } from 'autotel-aws/step-functions';\n * import { SFNClient } from '@aws-sdk/client-sfn';\n *\n * const sfn = new SFNClient({ region: 'us-east-1' });\n * const executor = new StepFunctionsExecutor(sfn, {\n * stateMachineArn: 'arn:aws:states:us-east-1:123456789:stateMachine:OrderProcessor'\n * });\n *\n * // Start execution with automatic trace context\n * const result = await executor.startExecution({\n * input: { orderId: '123', items: ['item1', 'item2'] },\n * name: 'order-123-execution'\n * });\n *\n * console.log('Execution ARN:', result.executionArn);\n * ```\n *\n * @example Express workflow (sync execution)\n * ```typescript\n * // Express workflows return synchronously\n * const result = await executor.startSyncExecution({\n * input: { orderId: '123' }\n * });\n *\n * if (result.status === 'SUCCEEDED') {\n * const output = JSON.parse(result.output || '{}');\n * console.log('Workflow output:', output);\n * }\n * ```\n */\nexport class StepFunctionsExecutor<\n \n TClient extends { send: (command: any) => Promise<any> } = any,\n> {\n private client: TClient;\n private config: Required<Pick<StepFunctionsExecutorConfig, 'stateMachineArn'>> &\n StepFunctionsExecutorConfig;\n private stateMachineName: string;\n\n constructor(client: TClient, config: StepFunctionsExecutorConfig) {\n this.client = wrapSDKClient(client as any, config.service) as TClient;\n this.config = {\n injectTraceContext: true,\n ...config,\n };\n // Extract state machine name from ARN (last segment)\n this.stateMachineName = config.stateMachineArn.split(':').pop() || 'unknown';\n }\n\n /**\n * Start a new execution of the state machine\n *\n * @param execution - Execution input and optional name\n * @returns Promise with execution ARN and start date\n */\n async startExecution<T extends Record<string, unknown>>(\n execution: ExecutionInput<T>,\n ): Promise<{\n executionArn?: string;\n startDate?: Date;\n }> {\n return trace(`stepfunctions.StartExecution`, async (ctx: TraceContext) => {\n ctx.setAttributes(\n buildStepFunctionsAttributes({\n stateMachineArn: this.config.stateMachineArn,\n }),\n );\n ctx.setAttribute('aws.stepfunctions.state_machine_name', this.stateMachineName);\n\n if (execution.name) {\n ctx.setAttribute('aws.stepfunctions.execution_name', execution.name);\n }\n\n // Optionally inject trace context\n const inputData = this.config.injectTraceContext\n ? injectTraceContext(execution.input)\n : execution.input;\n\n const input = {\n stateMachineArn: this.config.stateMachineArn,\n input: JSON.stringify(inputData),\n name: execution.name,\n traceHeader: execution.traceHeader,\n };\n\n try {\n const { StartExecutionCommand } = await import('@aws-sdk/client-sfn');\n const result = await this.client.send(new StartExecutionCommand(input));\n\n if (result.executionArn) {\n ctx.setAttribute('aws.stepfunctions.execution_arn', result.executionArn);\n }\n\n ctx.setStatus({ code: SpanStatusCode.OK });\n\n return {\n executionArn: result.executionArn,\n startDate: result.startDate,\n };\n } catch (error) {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'StartExecution failed',\n });\n throw error;\n }\n });\n }\n\n /**\n * Start a synchronous execution (Express workflows only)\n *\n * @param execution - Execution input and optional name\n * @returns Promise with execution result including output\n */\n async startSyncExecution<T extends Record<string, unknown>>(\n execution: ExecutionInput<T>,\n ): Promise<{\n executionArn?: string;\n status?: 'SUCCEEDED' | 'FAILED' | 'TIMED_OUT';\n output?: string;\n error?: string;\n cause?: string;\n billingDetails?: {\n billedMemoryUsedInMB?: number;\n billedDurationInMilliseconds?: number;\n };\n }> {\n return trace(`stepfunctions.StartSyncExecution`, async (ctx: TraceContext) => {\n ctx.setAttributes(\n buildStepFunctionsAttributes({\n stateMachineArn: this.config.stateMachineArn,\n }),\n );\n ctx.setAttribute('aws.stepfunctions.state_machine_name', this.stateMachineName);\n ctx.setAttribute('aws.stepfunctions.execution_type', 'express');\n\n if (execution.name) {\n ctx.setAttribute('aws.stepfunctions.execution_name', execution.name);\n }\n\n // Optionally inject trace context\n const inputData = this.config.injectTraceContext\n ? injectTraceContext(execution.input)\n : execution.input;\n\n const input = {\n stateMachineArn: this.config.stateMachineArn,\n input: JSON.stringify(inputData),\n name: execution.name,\n traceHeader: execution.traceHeader,\n };\n\n try {\n const { StartSyncExecutionCommand } = await import('@aws-sdk/client-sfn');\n const result = await this.client.send(new StartSyncExecutionCommand(input));\n\n if (result.executionArn) {\n ctx.setAttribute('aws.stepfunctions.execution_arn', result.executionArn);\n }\n if (result.status) {\n ctx.setAttribute('aws.stepfunctions.execution_status', result.status);\n }\n\n if (result.status === 'FAILED' || result.status === 'TIMED_OUT') {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: result.error || result.status,\n });\n } else {\n ctx.setStatus({ code: SpanStatusCode.OK });\n }\n\n return {\n executionArn: result.executionArn,\n status: result.status as 'SUCCEEDED' | 'FAILED' | 'TIMED_OUT' | undefined,\n output: result.output,\n error: result.error,\n cause: result.cause,\n billingDetails: result.billingDetails\n ? {\n billedMemoryUsedInMB: result.billingDetails.billedMemoryUsedInMB,\n billedDurationInMilliseconds:\n result.billingDetails.billedDurationInMilliseconds,\n }\n : undefined,\n };\n } catch (error) {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'StartSyncExecution failed',\n });\n throw error;\n }\n });\n }\n\n /**\n * Describe an execution\n *\n * @param executionArn - ARN of the execution to describe\n * @returns Promise with execution details\n */\n async describeExecution(executionArn: string): Promise<{\n executionArn?: string;\n stateMachineArn?: string;\n name?: string;\n status?: string;\n startDate?: Date;\n stopDate?: Date;\n input?: string;\n output?: string;\n error?: string;\n cause?: string;\n }> {\n return trace(`stepfunctions.DescribeExecution`, async (ctx: TraceContext) => {\n ctx.setAttributes(\n buildStepFunctionsAttributes({\n stateMachineArn: this.config.stateMachineArn,\n }),\n );\n ctx.setAttribute('aws.stepfunctions.execution_arn', executionArn);\n\n try {\n const { DescribeExecutionCommand } = await import('@aws-sdk/client-sfn');\n const result = await this.client.send(\n new DescribeExecutionCommand({ executionArn }),\n );\n\n if (result.status) {\n ctx.setAttribute('aws.stepfunctions.execution_status', result.status);\n }\n\n ctx.setStatus({ code: SpanStatusCode.OK });\n\n return {\n executionArn: result.executionArn,\n stateMachineArn: result.stateMachineArn,\n name: result.name,\n status: result.status,\n startDate: result.startDate,\n stopDate: result.stopDate,\n input: result.input,\n output: result.output,\n error: result.error,\n cause: result.cause,\n };\n } catch (error) {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'DescribeExecution failed',\n });\n throw error;\n }\n });\n }\n\n /**\n * Stop an execution\n *\n * @param executionArn - ARN of the execution to stop\n * @param options - Optional error and cause for the stop\n * @returns Promise with stop date\n */\n async stopExecution(\n executionArn: string,\n options?: { error?: string; cause?: string },\n ): Promise<{ stopDate?: Date }> {\n return trace(`stepfunctions.StopExecution`, async (ctx: TraceContext) => {\n ctx.setAttributes(\n buildStepFunctionsAttributes({\n stateMachineArn: this.config.stateMachineArn,\n }),\n );\n ctx.setAttribute('aws.stepfunctions.execution_arn', executionArn);\n\n try {\n const { StopExecutionCommand } = await import('@aws-sdk/client-sfn');\n const result = await this.client.send(\n new StopExecutionCommand({\n executionArn,\n error: options?.error,\n cause: options?.cause,\n }),\n );\n\n ctx.setStatus({ code: SpanStatusCode.OK });\n\n return { stopDate: result.stopDate };\n } catch (error) {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'StopExecution failed',\n });\n throw error;\n }\n });\n }\n}\n\n// ============================================================================\n// StepFunctionsActivityWorker Class\n// ============================================================================\n\n/**\n * Step Functions Activity Worker with trace context extraction\n *\n * Polls for activity tasks and processes them with automatic tracing.\n * Extracts trace context from task input for distributed tracing.\n *\n * @example Basic activity worker\n * ```typescript\n * import { StepFunctionsActivityWorker } from 'autotel-aws/step-functions';\n * import { SFNClient } from '@aws-sdk/client-sfn';\n *\n * const sfn = new SFNClient({ region: 'us-east-1' });\n * const worker = new StepFunctionsActivityWorker(sfn, {\n * activityArn: 'arn:aws:states:us-east-1:123456789:activity:ProcessPayment',\n * workerName: 'payment-worker-1'\n * });\n *\n * // Process tasks with automatic tracing\n * await worker.poll(async (input, taskToken, ctx) => {\n * ctx.setAttribute('payment.amount', input.amount);\n * ctx.setAttribute('payment.currency', input.currency);\n *\n * const result = await processPayment(input);\n *\n * ctx.setAttribute('payment.status', result.status);\n * return result;\n * });\n * ```\n *\n * @example Continuous polling with error handling\n * ```typescript\n * async function runWorker() {\n * while (true) {\n * try {\n * await worker.poll(async (input, taskToken, ctx) => {\n * return await processTask(input);\n * });\n * } catch (error) {\n * console.error('Worker error:', error);\n * // Brief pause before retrying\n * await new Promise(resolve => setTimeout(resolve, 1000));\n * }\n * }\n * }\n * ```\n */\nexport class StepFunctionsActivityWorker<\n \n TClient extends { send: (command: any) => Promise<any> } = any,\n> {\n private client: TClient;\n private config: Required<Pick<StepFunctionsActivityWorkerConfig, 'activityArn'>> &\n StepFunctionsActivityWorkerConfig;\n private activityName: string;\n\n constructor(client: TClient, config: StepFunctionsActivityWorkerConfig) {\n this.client = wrapSDKClient(client as any, config.service) as TClient;\n this.config = {\n extractTraceContext: true,\n ...config,\n };\n // Extract activity name from ARN\n this.activityName = config.activityArn.split(':').pop() || 'unknown';\n }\n\n /**\n * Poll for an activity task and process it\n *\n * @param processor - Function to process the task input\n * @returns Promise that resolves when the task is processed\n */\n async poll<TInput extends Record<string, unknown>, TOutput>(\n processor: (\n input: TInput,\n taskToken: string,\n ctx: TraceContext,\n ) => Promise<TOutput>,\n ): Promise<void> {\n return trace(`stepfunctions.activity.poll`, async (ctx: TraceContext) => {\n ctx.setAttribute('aws.stepfunctions.activity_arn', this.config.activityArn);\n ctx.setAttribute('aws.stepfunctions.activity_name', this.activityName);\n\n if (this.config.workerName) {\n ctx.setAttribute('aws.stepfunctions.worker_name', this.config.workerName);\n }\n\n try {\n // Poll for task\n const { GetActivityTaskCommand } = await import('@aws-sdk/client-sfn');\n const task = await this.client.send(\n new GetActivityTaskCommand({\n activityArn: this.config.activityArn,\n workerName: this.config.workerName,\n }),\n );\n\n if (!task.taskToken || !task.input) {\n // No task available (timeout)\n ctx.setAttribute('aws.stepfunctions.activity_task_received', false);\n ctx.setStatus({ code: SpanStatusCode.OK });\n return;\n }\n\n ctx.setAttribute('aws.stepfunctions.activity_task_received', true);\n\n // Parse input\n const rawInput = JSON.parse(task.input) as TInput & TraceContextFields;\n\n // Extract trace context if enabled\n if (this.config.extractTraceContext) {\n const parentContext = extractStepFunctionsContext(rawInput);\n if (parentContext) {\n ctx.setAttribute('aws.stepfunctions.trace_context_extracted', true);\n }\n }\n\n // Strip trace context from input\n const cleanInput = stripTraceContext(rawInput) as TInput;\n\n // Process the task\n const output = await processor(cleanInput, task.taskToken, ctx);\n\n // Send success\n const { SendTaskSuccessCommand } = await import('@aws-sdk/client-sfn');\n await this.client.send(\n new SendTaskSuccessCommand({\n taskToken: task.taskToken,\n output: JSON.stringify(output),\n }),\n );\n\n ctx.setStatus({ code: SpanStatusCode.OK });\n } catch (error) {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'Activity processing failed',\n });\n\n // If we have a task token, send failure\n // Note: In a real implementation, you'd want to track the token\n // This is simplified for the example\n\n throw error;\n }\n });\n }\n\n /**\n * Send a task heartbeat\n *\n * For long-running activities, send heartbeats to prevent timeout.\n *\n * @param taskToken - The task token from GetActivityTask\n */\n async sendHeartbeat(taskToken: string): Promise<void> {\n return trace(`stepfunctions.SendTaskHeartbeat`, async (ctx: TraceContext) => {\n ctx.setAttribute('aws.stepfunctions.activity_arn', this.config.activityArn);\n\n try {\n const { SendTaskHeartbeatCommand } = await import('@aws-sdk/client-sfn');\n await this.client.send(new SendTaskHeartbeatCommand({ taskToken }));\n\n ctx.setStatus({ code: SpanStatusCode.OK });\n } catch (error) {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'SendTaskHeartbeat failed',\n });\n throw error;\n }\n });\n }\n\n /**\n * Send task failure\n *\n * @param taskToken - The task token from GetActivityTask\n * @param error - Error code\n * @param cause - Error cause description\n */\n async sendFailure(\n taskToken: string,\n error: string,\n cause?: string,\n ): Promise<void> {\n return trace(`stepfunctions.SendTaskFailure`, async (ctx: TraceContext) => {\n ctx.setAttribute('aws.stepfunctions.activity_arn', this.config.activityArn);\n ctx.setAttribute('aws.stepfunctions.task_error', error);\n\n try {\n const { SendTaskFailureCommand } = await import('@aws-sdk/client-sfn');\n await this.client.send(\n new SendTaskFailureCommand({\n taskToken,\n error,\n cause,\n }),\n );\n\n ctx.setStatus({ code: SpanStatusCode.OK });\n } catch (error_) {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: error_ instanceof Error ? error_.message : 'SendTaskFailure failed',\n });\n throw error_;\n }\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export { __require };
|
|
9
|
+
//# sourceMappingURL=chunk-DGUM43GV.js.map
|
|
10
|
+
//# sourceMappingURL=chunk-DGUM43GV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-DGUM43GV.js"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkQ3DMMQ7K_cjs = require('./chunk-Q3DMMQ7K.cjs');
|
|
4
|
+
var autotel = require('autotel');
|
|
5
|
+
|
|
6
|
+
function traceS3(config) {
|
|
7
|
+
return function wrapper(fn) {
|
|
8
|
+
return autotel.trace(
|
|
9
|
+
`s3.${config.operation}`,
|
|
10
|
+
(ctx) => async (...args) => {
|
|
11
|
+
if (config.bucket) {
|
|
12
|
+
ctx.setAttributes(chunkQ3DMMQ7K_cjs.buildS3Attributes({ bucket: config.bucket }));
|
|
13
|
+
}
|
|
14
|
+
const handler = fn(ctx);
|
|
15
|
+
return handler(...args);
|
|
16
|
+
}
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
exports.traceS3 = traceS3;
|
|
22
|
+
//# sourceMappingURL=chunk-DHHLKZHI.cjs.map
|
|
23
|
+
//# sourceMappingURL=chunk-DHHLKZHI.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/s3/index.ts"],"names":["trace","buildS3Attributes"],"mappings":";;;;;AA6EO,SAAS,QAAQ,MAAA,EAAuB;AAC7C,EAAA,OAAO,SAAS,QACd,EAAA,EACsC;AAEtC,IAAA,OAAOA,aAAA;AAAA,MACL,CAAA,GAAA,EAAM,OAAO,SAAS,CAAA,CAAA;AAAA,MACtB,CAAC,GAAA,KACC,OAAA,GAAU,IAAA,KAAkC;AAE1C,QAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,UAAA,GAAA,CAAI,cAAcC,mCAAA,CAAkB,EAAE,QAAQ,MAAA,CAAO,MAAA,EAAQ,CAAC,CAAA;AAAA,QAChE;AAGA,QAAA,MAAM,OAAA,GAAU,GAAG,GAAG,CAAA;AACtB,QAAA,OAAO,OAAA,CAAQ,GAAG,IAAI,CAAA;AAAA,MACxB;AAAA,KACJ;AAAA,EACF,CAAA;AACF","file":"chunk-DHHLKZHI.cjs","sourcesContent":["/**\n * S3-specific instrumentation\n *\n * Provides semantic helpers for tracing S3 operations with proper OpenTelemetry\n * semantic conventions. Automatically sets `aws.s3.*` attributes.\n *\n * @example Basic usage with factory pattern\n * ```typescript\n * import { traceS3 } from 'autotel-aws/s3';\n * import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';\n *\n * const s3 = new S3Client({});\n *\n * export const getFile = traceS3({\n * operation: 'GetObject',\n * bucket: 'my-bucket'\n * })(ctx => async (key: string) => {\n * ctx.setAttribute('aws.s3.key', key);\n * return await s3.send(new GetObjectCommand({ Bucket: 'my-bucket', Key: key }));\n * });\n *\n * // Usage: await getFile('path/to/file.txt');\n * ```\n *\n * @example Dynamic bucket\n * ```typescript\n * export const getObject = traceS3({\n * operation: 'GetObject',\n * })(ctx => async (bucket: string, key: string) => {\n * ctx.setAttribute('aws.s3.bucket', bucket);\n * ctx.setAttribute('aws.s3.key', key);\n * return await s3.send(new GetObjectCommand({ Bucket: bucket, Key: key }));\n * });\n *\n * // Usage: await getObject('my-bucket', 'file.txt');\n * ```\n */\n\nimport { trace, type TraceContext } from 'autotel';\nimport { buildS3Attributes } from '../attributes';\n\n/**\n * S3 operation configuration\n */\nexport interface TraceS3Config {\n /**\n * S3 operation name (e.g., 'GetObject', 'PutObject', 'DeleteObject')\n * Used to generate the span name: `s3.{operation}`\n */\n operation: string;\n\n /**\n * Default bucket name for static configurations.\n * Can be overridden by setting `aws.s3.bucket` attribute in the handler.\n */\n bucket?: string;\n}\n\n/**\n * Trace S3 operations with semantic attributes\n *\n * Creates a traced function that automatically sets S3 semantic attributes\n * following OpenTelemetry conventions.\n *\n * @param config - S3 operation configuration\n * @returns A higher-order function that wraps your S3 operation with tracing\n *\n * @remarks\n * Semantic attributes set automatically:\n * - `aws.s3.bucket` - S3 bucket name (if provided in config)\n *\n * Additional attributes you should set in your handler:\n * - `aws.s3.key` - Object key\n * - `aws.s3.copy_source` - Source for copy operations\n *\n * @see https://opentelemetry.io/docs/specs/semconv/object-stores/s3/\n */\nexport function traceS3(config: TraceS3Config) {\n return function wrapper<TArgs extends unknown[], TReturn>(\n fn: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): (...args: TArgs) => Promise<TReturn> {\n // Use autotel's trace() which properly handles the factory pattern\n return trace(\n `s3.${config.operation}`,\n (ctx: TraceContext) =>\n async (...args: TArgs): Promise<TReturn> => {\n // Set S3 semantic attributes\n if (config.bucket) {\n ctx.setAttributes(buildS3Attributes({ bucket: config.bucket }));\n }\n\n // Get the user's handler and execute with forwarded arguments\n const handler = fn(ctx);\n return handler(...args);\n },\n );\n };\n}\n"]}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { wrapSDKClient } from './chunk-YG56NRIO.js';
|
|
2
|
+
import { __require } from './chunk-DGUM43GV.js';
|
|
3
|
+
|
|
4
|
+
// src/sdk/auto-instrument.ts
|
|
5
|
+
var INSTRUMENTED_SYMBOL = Symbol.for("autotel-aws.instrumented");
|
|
6
|
+
var globalAutoInstrumentEnabled = false;
|
|
7
|
+
var originalSmithyClientSend = null;
|
|
8
|
+
function isInstrumented(client) {
|
|
9
|
+
return typeof client === "object" && client !== null && client[INSTRUMENTED_SYMBOL] === true;
|
|
10
|
+
}
|
|
11
|
+
function markAsInstrumented(client) {
|
|
12
|
+
client[INSTRUMENTED_SYMBOL] = true;
|
|
13
|
+
return client;
|
|
14
|
+
}
|
|
15
|
+
function instrumentSDK(client, config) {
|
|
16
|
+
if (isInstrumented(client)) {
|
|
17
|
+
return client;
|
|
18
|
+
}
|
|
19
|
+
const wrappedClient = wrapSDKClient(client, config?.service);
|
|
20
|
+
return markAsInstrumented(wrappedClient);
|
|
21
|
+
}
|
|
22
|
+
function createTracedClient(ClientClass, config) {
|
|
23
|
+
const client = new ClientClass(config);
|
|
24
|
+
return instrumentSDK(client, config);
|
|
25
|
+
}
|
|
26
|
+
function autoInstrumentAWS(config) {
|
|
27
|
+
if (globalAutoInstrumentEnabled) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
let SmithyClient;
|
|
31
|
+
try {
|
|
32
|
+
SmithyClient = __require("@aws-sdk/smithy-client").Client;
|
|
33
|
+
} catch {
|
|
34
|
+
try {
|
|
35
|
+
SmithyClient = __require("@smithy/smithy-client").Client;
|
|
36
|
+
} catch {
|
|
37
|
+
console.warn(
|
|
38
|
+
"[autotel-aws] autoInstrumentAWS() requires @aws-sdk/smithy-client or @smithy/smithy-client. Install an AWS SDK v3 client package (e.g., @aws-sdk/client-s3) or use instrumentSDK() directly."
|
|
39
|
+
);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
originalSmithyClientSend = SmithyClient.prototype.send;
|
|
44
|
+
const originalSend = SmithyClient.prototype.send;
|
|
45
|
+
SmithyClient.prototype.send = function patchedSend(command, ...args) {
|
|
46
|
+
if (isInstrumented(this)) {
|
|
47
|
+
return originalSend.call(this, command, ...args);
|
|
48
|
+
}
|
|
49
|
+
const wrappedClient = wrapSDKClient(this, config?.service);
|
|
50
|
+
return wrappedClient.send(command, ...args);
|
|
51
|
+
};
|
|
52
|
+
globalAutoInstrumentEnabled = true;
|
|
53
|
+
}
|
|
54
|
+
function disableAutoInstrumentAWS() {
|
|
55
|
+
if (!globalAutoInstrumentEnabled || !originalSmithyClientSend) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
let SmithyClient;
|
|
59
|
+
try {
|
|
60
|
+
SmithyClient = __require("@aws-sdk/smithy-client").Client;
|
|
61
|
+
} catch {
|
|
62
|
+
try {
|
|
63
|
+
SmithyClient = __require("@smithy/smithy-client").Client;
|
|
64
|
+
} catch {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
SmithyClient.prototype.send = originalSmithyClientSend;
|
|
69
|
+
originalSmithyClientSend = null;
|
|
70
|
+
globalAutoInstrumentEnabled = false;
|
|
71
|
+
}
|
|
72
|
+
function isAutoInstrumentEnabled() {
|
|
73
|
+
return globalAutoInstrumentEnabled;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { autoInstrumentAWS, createTracedClient, disableAutoInstrumentAWS, instrumentSDK, isAutoInstrumentEnabled };
|
|
77
|
+
//# sourceMappingURL=chunk-FKZOELBT.js.map
|
|
78
|
+
//# sourceMappingURL=chunk-FKZOELBT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sdk/auto-instrument.ts"],"names":[],"mappings":";;;;AA2BA,IAAM,mBAAA,GAAsB,MAAA,CAAO,GAAA,CAAI,0BAA0B,CAAA;AAGjE,IAAI,2BAAA,GAA8B,KAAA;AAGlC,IAAI,wBAAA,GAA8E,IAAA;AAKlF,SAAS,eAAe,MAAA,EAA0B;AAChD,EAAA,OACE,OAAO,MAAA,KAAW,QAAA,IAClB,WAAW,IAAA,IACV,MAAA,CAAmC,mBAAmB,CAAA,KAAM,IAAA;AAEjE;AAKA,SAAS,mBAAsB,MAAA,EAAc;AAC3C,EAAC,MAAA,CAAmC,mBAAmB,CAAA,GAAI,IAAA;AAC3D,EAAA,OAAO,MAAA;AACT;AAuCO,SAAS,aAAA,CACd,QACA,MAAA,EACG;AAEH,EAAA,IAAI,cAAA,CAAe,MAAM,CAAA,EAAG;AAC1B,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,MAAM,aAAA,GAAgB,aAAA,CAAc,MAAA,EAAQ,MAAA,EAAQ,OAAO,CAAA;AAC3D,EAAA,OAAO,mBAAmB,aAAa,CAAA;AACzC;AAyBO,SAAS,kBAAA,CAId,aACA,MAAA,EACiB;AAEjB,EAAA,MAAM,MAAA,GAAS,IAAI,WAAA,CAAY,MAAa,CAAA;AAC5C,EAAA,OAAO,aAAA,CAAc,QAAQ,MAAM,CAAA;AACrC;AA6CO,SAAS,kBAAkB,MAAA,EAAyC;AAEzE,EAAA,IAAI,2BAAA,EAA6B;AAC/B,IAAA;AAAA,EACF;AAIA,EAAA,IAAI,YAAA;AACJ,EAAA,IAAI;AAGF,IAAA,YAAA,GAAe,SAAA,CAAQ,wBAAwB,CAAA,CAAE,MAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AAEN,IAAA,IAAI;AAEF,MAAA,YAAA,GAAe,SAAA,CAAQ,uBAAuB,CAAA,CAAE,MAAA;AAAA,IAClD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN;AAAA,OAEF;AACA,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,wBAAA,GAA2B,aAAa,SAAA,CAAU,IAAA;AAGlD,EAAA,MAAM,YAAA,GAAe,aAAa,SAAA,CAAU,IAAA;AAE5C,EAAA,YAAA,CAAa,SAAA,CAAU,IAAA,GAAO,SAAS,WAAA,CAErC,YACG,IAAA,EACe;AAElB,IAAA,IAAI,cAAA,CAAe,IAAI,CAAA,EAAG;AACxB,MAAA,OAAO,YAAA,CAAa,IAAA,CAAK,IAAA,EAAM,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA,IACjD;AAIA,IAAA,MAAM,aAAA,GAAgB,aAAA,CAAc,IAAA,EAAoD,MAAA,EAAQ,OAAO,CAAA;AAEvG,IAAA,OAAQ,aAAA,CAAsB,IAAA,CAAK,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA,EACrD,CAAA;AAEA,EAAA,2BAAA,GAA8B,IAAA;AAChC;AAmBO,SAAS,wBAAA,GAAiC;AAC/C,EAAA,IAAI,CAAC,2BAAA,IAA+B,CAAC,wBAAA,EAA0B;AAC7D,IAAA;AAAA,EACF;AAGA,EAAA,IAAI,YAAA;AACJ,EAAA,IAAI;AAEF,IAAA,YAAA,GAAe,SAAA,CAAQ,wBAAwB,CAAA,CAAE,MAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AACN,IAAA,IAAI;AAEF,MAAA,YAAA,GAAe,SAAA,CAAQ,uBAAuB,CAAA,CAAE,MAAA;AAAA,IAClD,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,YAAA,CAAa,UAAU,IAAA,GAAO,wBAAA;AAC9B,EAAA,wBAAA,GAA2B,IAAA;AAC3B,EAAA,2BAAA,GAA8B,KAAA;AAChC;AAKO,SAAS,uBAAA,GAAmC;AACjD,EAAA,OAAO,2BAAA;AACT","file":"chunk-FKZOELBT.js","sourcesContent":["/**\n * AWS SDK v3 auto-instrumentation\n *\n * Provides multiple approaches for instrumenting AWS SDK v3 clients:\n * 1. `instrumentSDK()` - Wrap an existing client instance\n * 2. `createTracedClient()` - Create a pre-instrumented client\n * 3. `autoInstrumentAWS()` - Globally patch all AWS SDK clients\n *\n * @example Basic instrumentation\n * ```typescript\n * import { instrumentSDK } from 'autotel-aws/sdk';\n * import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';\n *\n * const s3 = instrumentSDK(new S3Client({ region: 'us-east-1' }));\n *\n * // All send() calls are now traced\n * await s3.send(new PutObjectCommand({ Bucket: 'my-bucket', Key: 'file.txt' }));\n * ```\n */\n\n// Type-only import from optional peer dependency\n// @ts-expect-error - Optional peer dependency, may not be installed\nimport type { Client, Command } from '@aws-sdk/smithy-client';\nimport { wrapSDKClient } from '../common/sdk-wrapper';\nimport type { SDKInstrumentationConfig } from '../config';\n\n// Symbol to mark clients as instrumented (prevents double-wrapping)\nconst INSTRUMENTED_SYMBOL = Symbol.for('autotel-aws.instrumented');\n\n// Track whether global auto-instrumentation is active\nlet globalAutoInstrumentEnabled = false;\n\n// Store original send method for restoration\nlet originalSmithyClientSend: ((...args: unknown[]) => Promise<unknown>) | null = null;\n\n/**\n * Check if a client is already instrumented\n */\nfunction isInstrumented(client: unknown): boolean {\n return (\n typeof client === 'object' &&\n client !== null &&\n (client as Record<symbol, boolean>)[INSTRUMENTED_SYMBOL] === true\n );\n}\n\n/**\n * Mark a client as instrumented\n */\nfunction markAsInstrumented<T>(client: T): T {\n (client as Record<symbol, boolean>)[INSTRUMENTED_SYMBOL] = true;\n return client;\n}\n\n/**\n * Instrument an existing AWS SDK v3 client\n *\n * Wraps the client's `send()` method to automatically create spans\n * for all AWS API calls with proper semantic attributes.\n *\n * @param client - An AWS SDK v3 client instance\n * @param config - Optional instrumentation configuration\n * @returns The instrumented client (same instance, modified)\n *\n * @example Basic usage\n * ```typescript\n * import { instrumentSDK } from 'autotel-aws/sdk';\n * import { S3Client } from '@aws-sdk/client-s3';\n *\n * const s3 = instrumentSDK(new S3Client({ region: 'us-east-1' }));\n * ```\n *\n * @example With configuration\n * ```typescript\n * const s3 = instrumentSDK(new S3Client({}), {\n * service: 's3',\n * captureRequest: true,\n * captureResponse: true\n * });\n * ```\n *\n * @remarks\n * Semantic attributes set automatically:\n * - `rpc.system` - 'aws-api'\n * - `rpc.service` - AWS service name (e.g., 'S3', 'DynamoDB')\n * - `rpc.method` - Operation name (e.g., 'GetObject', 'PutItem')\n * - `aws.request_id` - AWS request ID from response\n * - `http.status_code` - HTTP status code\n *\n * @see https://opentelemetry.io/docs/specs/semconv/cloud-providers/aws-sdk/\n */\nexport function instrumentSDK<T extends Client<unknown, unknown, unknown, unknown>>(\n client: T,\n config?: SDKInstrumentationConfig,\n): T {\n // Prevent double-instrumentation\n if (isInstrumented(client)) {\n return client;\n }\n\n const wrappedClient = wrapSDKClient(client, config?.service);\n return markAsInstrumented(wrappedClient);\n}\n\n/**\n * Create a pre-instrumented AWS SDK v3 client\n *\n * Convenience factory that creates and instruments a client in one call.\n *\n * @param ClientClass - The AWS SDK client class constructor\n * @param config - Client configuration merged with instrumentation config\n * @returns A new instrumented client instance\n *\n * @example\n * ```typescript\n * import { createTracedClient } from 'autotel-aws/sdk';\n * import { S3Client } from '@aws-sdk/client-s3';\n * import { DynamoDBClient } from '@aws-sdk/client-dynamodb';\n *\n * // Create instrumented clients\n * const s3 = createTracedClient(S3Client, { region: 'us-east-1' });\n * const dynamodb = createTracedClient(DynamoDBClient, {\n * region: 'us-east-1',\n * captureRequest: true\n * });\n * ```\n */\nexport function createTracedClient<\n \n T extends new (...args: any[]) => Client<unknown, unknown, unknown, unknown>,\n>(\n ClientClass: T,\n config?: SDKInstrumentationConfig & ConstructorParameters<T>[0],\n): InstanceType<T> {\n \n const client = new ClientClass(config as any);\n return instrumentSDK(client, config) as InstanceType<T>;\n}\n\n/**\n * Auto-instrument all AWS SDK v3 clients globally\n *\n * Patches the AWS SDK's base Client class to automatically instrument\n * all client instances created after this call. This is the most convenient\n * approach but requires the AWS SDK to be installed.\n *\n * Call this once at application startup, before creating any clients.\n *\n * @param config - Optional default instrumentation configuration\n *\n * @example Basic usage\n * ```typescript\n * import { autoInstrumentAWS } from 'autotel-aws/sdk';\n *\n * // Call once at startup\n * autoInstrumentAWS();\n *\n * // All subsequent clients are automatically instrumented\n * const s3 = new S3Client({ region: 'us-east-1' });\n * const dynamodb = new DynamoDBClient({ region: 'us-east-1' });\n *\n * // Both are traced automatically\n * await s3.send(new GetObjectCommand({ Bucket: 'b', Key: 'k' }));\n * await dynamodb.send(new GetItemCommand({ TableName: 't', Key: {} }));\n * ```\n *\n * @example With default configuration\n * ```typescript\n * autoInstrumentAWS({\n * captureRequest: false,\n * captureResponse: false\n * });\n * ```\n *\n * @remarks\n * - This function is idempotent - calling it multiple times has no effect\n * - Clients created before calling this function are NOT instrumented\n * - Use `instrumentSDK()` for clients created before auto-instrumentation\n * - Requires `@aws-sdk/smithy-client` to be installed (peer dependency)\n *\n * @throws Error if AWS SDK is not installed\n */\nexport function autoInstrumentAWS(config?: SDKInstrumentationConfig): void {\n // Idempotency check\n if (globalAutoInstrumentEnabled) {\n return;\n }\n\n // Try to get the smithy-client module\n \n let SmithyClient: any;\n try {\n // Dynamic require to avoid bundling issues\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n SmithyClient = require('@aws-sdk/smithy-client').Client;\n } catch {\n // Try the core package (newer SDK versions)\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n SmithyClient = require('@smithy/smithy-client').Client;\n } catch {\n console.warn(\n '[autotel-aws] autoInstrumentAWS() requires @aws-sdk/smithy-client or @smithy/smithy-client. ' +\n 'Install an AWS SDK v3 client package (e.g., @aws-sdk/client-s3) or use instrumentSDK() directly.',\n );\n return;\n }\n }\n\n // Store original send for potential restoration\n originalSmithyClientSend = SmithyClient.prototype.send;\n\n // Patch the prototype's send method\n const originalSend = SmithyClient.prototype.send;\n\n SmithyClient.prototype.send = function patchedSend(\n this: Client<unknown, unknown, unknown, unknown>,\n command: Command<unknown, unknown, unknown, unknown, unknown>,\n ...args: unknown[]\n ): Promise<unknown> {\n // Skip if this specific client is already instrumented (via instrumentSDK)\n if (isInstrumented(this)) {\n return originalSend.call(this, command, ...args);\n }\n\n // Create a one-time wrapped client for this call\n // This is less efficient than pre-wrapping, but ensures all calls are traced\n const wrappedClient = wrapSDKClient(this as Client<unknown, unknown, unknown, unknown>, config?.service);\n \n return (wrappedClient as any).send(command, ...args);\n };\n\n globalAutoInstrumentEnabled = true;\n}\n\n/**\n * Disable global auto-instrumentation\n *\n * Restores the original AWS SDK behavior. Useful for testing or\n * when you need to disable instrumentation temporarily.\n *\n * @example\n * ```typescript\n * import { autoInstrumentAWS, disableAutoInstrumentAWS } from 'autotel-aws/sdk';\n *\n * autoInstrumentAWS();\n * // ... use instrumented clients ...\n *\n * disableAutoInstrumentAWS();\n * // Subsequent operations are not traced\n * ```\n */\nexport function disableAutoInstrumentAWS(): void {\n if (!globalAutoInstrumentEnabled || !originalSmithyClientSend) {\n return;\n }\n\n \n let SmithyClient: any;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n SmithyClient = require('@aws-sdk/smithy-client').Client;\n } catch {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n SmithyClient = require('@smithy/smithy-client').Client;\n } catch {\n return;\n }\n }\n\n // Restore original send\n SmithyClient.prototype.send = originalSmithyClientSend;\n originalSmithyClientSend = null;\n globalAutoInstrumentEnabled = false;\n}\n\n/**\n * Check if global auto-instrumentation is enabled\n */\nexport function isAutoInstrumentEnabled(): boolean {\n return globalAutoInstrumentEnabled;\n}\n"]}
|