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,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS semantic attribute helpers
|
|
3
|
+
* Following OpenTelemetry AWS semantic conventions
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* AWS semantic attribute keys
|
|
7
|
+
*/
|
|
8
|
+
declare const AWS_ATTRS: {
|
|
9
|
+
readonly LAMBDA_FUNCTION_NAME: "faas.name";
|
|
10
|
+
readonly LAMBDA_FUNCTION_VERSION: "faas.version";
|
|
11
|
+
readonly LAMBDA_INVOCATION_ID: "faas.invocation_id";
|
|
12
|
+
readonly LAMBDA_COLD_START: "faas.coldstart";
|
|
13
|
+
readonly LAMBDA_TRIGGER: "faas.trigger";
|
|
14
|
+
readonly AWS_SERVICE: "rpc.service";
|
|
15
|
+
readonly AWS_OPERATION: "rpc.method";
|
|
16
|
+
readonly AWS_REQUEST_ID: "aws.request_id";
|
|
17
|
+
readonly AWS_EXTENDED_REQUEST_ID: "aws.extended_request_id";
|
|
18
|
+
readonly AWS_CF_ID: "aws.cf_id";
|
|
19
|
+
readonly DDB_TABLE_NAMES: "aws.dynamodb.table_names";
|
|
20
|
+
readonly DDB_CONSUMED_CAPACITY: "aws.dynamodb.consumed_capacity";
|
|
21
|
+
readonly S3_BUCKET: "aws.s3.bucket";
|
|
22
|
+
readonly S3_KEY: "aws.s3.key";
|
|
23
|
+
readonly S3_COPY_SOURCE: "aws.s3.copy_source";
|
|
24
|
+
readonly SQS_QUEUE_NAME: "messaging.destination.name";
|
|
25
|
+
readonly SQS_QUEUE_URL: "aws.sqs.queue_url";
|
|
26
|
+
readonly SQS_MESSAGE_ID: "messaging.message.id";
|
|
27
|
+
readonly SNS_TOPIC_ARN: "messaging.destination.name";
|
|
28
|
+
readonly SNS_MESSAGE_ID: "messaging.message.id";
|
|
29
|
+
readonly KINESIS_STREAM_NAME: "messaging.destination.name";
|
|
30
|
+
readonly KINESIS_SHARD_ID: "aws.kinesis.shard_id";
|
|
31
|
+
readonly SFN_STATE_MACHINE_ARN: "aws.stepfunctions.state_machine_arn";
|
|
32
|
+
readonly SFN_EXECUTION_ARN: "aws.stepfunctions.execution_arn";
|
|
33
|
+
readonly SFN_ACTIVITY_ARN: "aws.stepfunctions.activity_arn";
|
|
34
|
+
readonly EVENTBRIDGE_EVENT_BUS: "aws.eventbridge.event_bus";
|
|
35
|
+
readonly EVENTBRIDGE_SOURCE: "aws.eventbridge.source";
|
|
36
|
+
readonly EVENTBRIDGE_DETAIL_TYPE: "aws.eventbridge.detail_type";
|
|
37
|
+
readonly XRAY_ANNOTATIONS: "aws.xray.annotations";
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Build Lambda span attributes
|
|
41
|
+
*/
|
|
42
|
+
declare function buildLambdaAttributes(context: {
|
|
43
|
+
awsRequestId: string;
|
|
44
|
+
functionName: string;
|
|
45
|
+
functionVersion: string;
|
|
46
|
+
coldStart?: boolean;
|
|
47
|
+
trigger?: string;
|
|
48
|
+
}): Record<string, string | boolean>;
|
|
49
|
+
/**
|
|
50
|
+
* Build AWS SDK span attributes
|
|
51
|
+
*/
|
|
52
|
+
declare function buildSDKAttributes(metadata: {
|
|
53
|
+
service: string;
|
|
54
|
+
operation: string;
|
|
55
|
+
requestId?: string;
|
|
56
|
+
httpStatusCode?: number;
|
|
57
|
+
extendedRequestId?: string;
|
|
58
|
+
cfId?: string;
|
|
59
|
+
}): Record<string, string | number>;
|
|
60
|
+
/**
|
|
61
|
+
* Build DynamoDB span attributes
|
|
62
|
+
*/
|
|
63
|
+
declare function buildDynamoDBAttributes(operation: {
|
|
64
|
+
tableName: string;
|
|
65
|
+
operation: string;
|
|
66
|
+
consumedCapacity?: number;
|
|
67
|
+
}): Record<string, string | number | string[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Build S3 span attributes
|
|
70
|
+
*/
|
|
71
|
+
declare function buildS3Attributes(operation: {
|
|
72
|
+
bucket: string;
|
|
73
|
+
key?: string;
|
|
74
|
+
copySource?: string;
|
|
75
|
+
}): Record<string, string>;
|
|
76
|
+
/**
|
|
77
|
+
* Build SQS span attributes
|
|
78
|
+
*/
|
|
79
|
+
declare function buildSQSAttributes(operation: {
|
|
80
|
+
queueName: string;
|
|
81
|
+
queueUrl?: string;
|
|
82
|
+
messageId?: string;
|
|
83
|
+
operation: 'send' | 'receive';
|
|
84
|
+
}): Record<string, string>;
|
|
85
|
+
/**
|
|
86
|
+
* Build SNS span attributes
|
|
87
|
+
*/
|
|
88
|
+
declare function buildSNSAttributes(operation: {
|
|
89
|
+
topicArn: string;
|
|
90
|
+
messageId?: string;
|
|
91
|
+
}): Record<string, string>;
|
|
92
|
+
/**
|
|
93
|
+
* Build Kinesis span attributes
|
|
94
|
+
*/
|
|
95
|
+
declare function buildKinesisAttributes(operation: {
|
|
96
|
+
streamName: string;
|
|
97
|
+
shardId?: string;
|
|
98
|
+
operation: 'put' | 'get';
|
|
99
|
+
}): Record<string, string>;
|
|
100
|
+
/**
|
|
101
|
+
* Build Step Functions span attributes
|
|
102
|
+
*/
|
|
103
|
+
declare function buildStepFunctionsAttributes(operation: {
|
|
104
|
+
stateMachineArn: string;
|
|
105
|
+
executionArn?: string;
|
|
106
|
+
activityArn?: string;
|
|
107
|
+
}): Record<string, string>;
|
|
108
|
+
/**
|
|
109
|
+
* Build EventBridge span attributes
|
|
110
|
+
*/
|
|
111
|
+
declare function buildEventBridgeAttributes(operation: {
|
|
112
|
+
eventBus: string;
|
|
113
|
+
source: string;
|
|
114
|
+
detailType: string;
|
|
115
|
+
}): Record<string, string>;
|
|
116
|
+
|
|
117
|
+
export { AWS_ATTRS, buildDynamoDBAttributes, buildEventBridgeAttributes, buildKinesisAttributes, buildLambdaAttributes, buildS3Attributes, buildSDKAttributes, buildSNSAttributes, buildSQSAttributes, buildStepFunctionsAttributes };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS semantic attribute helpers
|
|
3
|
+
* Following OpenTelemetry AWS semantic conventions
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* AWS semantic attribute keys
|
|
7
|
+
*/
|
|
8
|
+
declare const AWS_ATTRS: {
|
|
9
|
+
readonly LAMBDA_FUNCTION_NAME: "faas.name";
|
|
10
|
+
readonly LAMBDA_FUNCTION_VERSION: "faas.version";
|
|
11
|
+
readonly LAMBDA_INVOCATION_ID: "faas.invocation_id";
|
|
12
|
+
readonly LAMBDA_COLD_START: "faas.coldstart";
|
|
13
|
+
readonly LAMBDA_TRIGGER: "faas.trigger";
|
|
14
|
+
readonly AWS_SERVICE: "rpc.service";
|
|
15
|
+
readonly AWS_OPERATION: "rpc.method";
|
|
16
|
+
readonly AWS_REQUEST_ID: "aws.request_id";
|
|
17
|
+
readonly AWS_EXTENDED_REQUEST_ID: "aws.extended_request_id";
|
|
18
|
+
readonly AWS_CF_ID: "aws.cf_id";
|
|
19
|
+
readonly DDB_TABLE_NAMES: "aws.dynamodb.table_names";
|
|
20
|
+
readonly DDB_CONSUMED_CAPACITY: "aws.dynamodb.consumed_capacity";
|
|
21
|
+
readonly S3_BUCKET: "aws.s3.bucket";
|
|
22
|
+
readonly S3_KEY: "aws.s3.key";
|
|
23
|
+
readonly S3_COPY_SOURCE: "aws.s3.copy_source";
|
|
24
|
+
readonly SQS_QUEUE_NAME: "messaging.destination.name";
|
|
25
|
+
readonly SQS_QUEUE_URL: "aws.sqs.queue_url";
|
|
26
|
+
readonly SQS_MESSAGE_ID: "messaging.message.id";
|
|
27
|
+
readonly SNS_TOPIC_ARN: "messaging.destination.name";
|
|
28
|
+
readonly SNS_MESSAGE_ID: "messaging.message.id";
|
|
29
|
+
readonly KINESIS_STREAM_NAME: "messaging.destination.name";
|
|
30
|
+
readonly KINESIS_SHARD_ID: "aws.kinesis.shard_id";
|
|
31
|
+
readonly SFN_STATE_MACHINE_ARN: "aws.stepfunctions.state_machine_arn";
|
|
32
|
+
readonly SFN_EXECUTION_ARN: "aws.stepfunctions.execution_arn";
|
|
33
|
+
readonly SFN_ACTIVITY_ARN: "aws.stepfunctions.activity_arn";
|
|
34
|
+
readonly EVENTBRIDGE_EVENT_BUS: "aws.eventbridge.event_bus";
|
|
35
|
+
readonly EVENTBRIDGE_SOURCE: "aws.eventbridge.source";
|
|
36
|
+
readonly EVENTBRIDGE_DETAIL_TYPE: "aws.eventbridge.detail_type";
|
|
37
|
+
readonly XRAY_ANNOTATIONS: "aws.xray.annotations";
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Build Lambda span attributes
|
|
41
|
+
*/
|
|
42
|
+
declare function buildLambdaAttributes(context: {
|
|
43
|
+
awsRequestId: string;
|
|
44
|
+
functionName: string;
|
|
45
|
+
functionVersion: string;
|
|
46
|
+
coldStart?: boolean;
|
|
47
|
+
trigger?: string;
|
|
48
|
+
}): Record<string, string | boolean>;
|
|
49
|
+
/**
|
|
50
|
+
* Build AWS SDK span attributes
|
|
51
|
+
*/
|
|
52
|
+
declare function buildSDKAttributes(metadata: {
|
|
53
|
+
service: string;
|
|
54
|
+
operation: string;
|
|
55
|
+
requestId?: string;
|
|
56
|
+
httpStatusCode?: number;
|
|
57
|
+
extendedRequestId?: string;
|
|
58
|
+
cfId?: string;
|
|
59
|
+
}): Record<string, string | number>;
|
|
60
|
+
/**
|
|
61
|
+
* Build DynamoDB span attributes
|
|
62
|
+
*/
|
|
63
|
+
declare function buildDynamoDBAttributes(operation: {
|
|
64
|
+
tableName: string;
|
|
65
|
+
operation: string;
|
|
66
|
+
consumedCapacity?: number;
|
|
67
|
+
}): Record<string, string | number | string[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Build S3 span attributes
|
|
70
|
+
*/
|
|
71
|
+
declare function buildS3Attributes(operation: {
|
|
72
|
+
bucket: string;
|
|
73
|
+
key?: string;
|
|
74
|
+
copySource?: string;
|
|
75
|
+
}): Record<string, string>;
|
|
76
|
+
/**
|
|
77
|
+
* Build SQS span attributes
|
|
78
|
+
*/
|
|
79
|
+
declare function buildSQSAttributes(operation: {
|
|
80
|
+
queueName: string;
|
|
81
|
+
queueUrl?: string;
|
|
82
|
+
messageId?: string;
|
|
83
|
+
operation: 'send' | 'receive';
|
|
84
|
+
}): Record<string, string>;
|
|
85
|
+
/**
|
|
86
|
+
* Build SNS span attributes
|
|
87
|
+
*/
|
|
88
|
+
declare function buildSNSAttributes(operation: {
|
|
89
|
+
topicArn: string;
|
|
90
|
+
messageId?: string;
|
|
91
|
+
}): Record<string, string>;
|
|
92
|
+
/**
|
|
93
|
+
* Build Kinesis span attributes
|
|
94
|
+
*/
|
|
95
|
+
declare function buildKinesisAttributes(operation: {
|
|
96
|
+
streamName: string;
|
|
97
|
+
shardId?: string;
|
|
98
|
+
operation: 'put' | 'get';
|
|
99
|
+
}): Record<string, string>;
|
|
100
|
+
/**
|
|
101
|
+
* Build Step Functions span attributes
|
|
102
|
+
*/
|
|
103
|
+
declare function buildStepFunctionsAttributes(operation: {
|
|
104
|
+
stateMachineArn: string;
|
|
105
|
+
executionArn?: string;
|
|
106
|
+
activityArn?: string;
|
|
107
|
+
}): Record<string, string>;
|
|
108
|
+
/**
|
|
109
|
+
* Build EventBridge span attributes
|
|
110
|
+
*/
|
|
111
|
+
declare function buildEventBridgeAttributes(operation: {
|
|
112
|
+
eventBus: string;
|
|
113
|
+
source: string;
|
|
114
|
+
detailType: string;
|
|
115
|
+
}): Record<string, string>;
|
|
116
|
+
|
|
117
|
+
export { AWS_ATTRS, buildDynamoDBAttributes, buildEventBridgeAttributes, buildKinesisAttributes, buildLambdaAttributes, buildS3Attributes, buildSDKAttributes, buildSNSAttributes, buildSQSAttributes, buildStepFunctionsAttributes };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { AWS_ATTRS, buildDynamoDBAttributes, buildEventBridgeAttributes, buildKinesisAttributes, buildLambdaAttributes, buildS3Attributes, buildSDKAttributes, buildSNSAttributes, buildSQSAttributes, buildStepFunctionsAttributes } from './chunk-I4CKQ4RD.js';
|
|
2
|
+
import './chunk-DGUM43GV.js';
|
|
3
|
+
//# sourceMappingURL=attributes.js.map
|
|
4
|
+
//# sourceMappingURL=attributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"attributes.js"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkQ3DMMQ7K_cjs = require('./chunk-Q3DMMQ7K.cjs');
|
|
4
|
+
var api = require('@opentelemetry/api');
|
|
5
|
+
var propagatorAwsXray = require('@opentelemetry/propagator-aws-xray');
|
|
6
|
+
|
|
7
|
+
var xrayConfig = {};
|
|
8
|
+
function configureXRay(config) {
|
|
9
|
+
xrayConfig = { ...xrayConfig, ...config };
|
|
10
|
+
}
|
|
11
|
+
var annotationMap = /* @__PURE__ */ new WeakMap();
|
|
12
|
+
function setXRayAnnotation(key, value) {
|
|
13
|
+
const span = api.trace.getActiveSpan();
|
|
14
|
+
if (!span) return;
|
|
15
|
+
span.setAttribute(key, value);
|
|
16
|
+
let annotations = annotationMap.get(span);
|
|
17
|
+
if (!annotations) {
|
|
18
|
+
annotations = /* @__PURE__ */ new Set();
|
|
19
|
+
annotationMap.set(span, annotations);
|
|
20
|
+
}
|
|
21
|
+
if (!annotations.has(key)) {
|
|
22
|
+
annotations.add(key);
|
|
23
|
+
span.setAttribute(chunkQ3DMMQ7K_cjs.AWS_ATTRS.XRAY_ANNOTATIONS, [...annotations].join(","));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function setXRayMetadata(key, value) {
|
|
27
|
+
const span = api.trace.getActiveSpan();
|
|
28
|
+
if (!span) return;
|
|
29
|
+
if (typeof value === "object") {
|
|
30
|
+
try {
|
|
31
|
+
span.setAttribute(key, JSON.stringify(value));
|
|
32
|
+
} catch {
|
|
33
|
+
span.setAttribute(key, "<serialization-failed>");
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
span.setAttribute(key, value);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
Object.defineProperty(exports, "AWSXRayPropagator", {
|
|
41
|
+
enumerable: true,
|
|
42
|
+
get: function () { return propagatorAwsXray.AWSXRayPropagator; }
|
|
43
|
+
});
|
|
44
|
+
exports.configureXRay = configureXRay;
|
|
45
|
+
exports.setXRayAnnotation = setXRayAnnotation;
|
|
46
|
+
exports.setXRayMetadata = setXRayMetadata;
|
|
47
|
+
//# sourceMappingURL=chunk-35F3UBOO.cjs.map
|
|
48
|
+
//# sourceMappingURL=chunk-35F3UBOO.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/xray/annotations.ts"],"names":["trace","AWS_ATTRS"],"mappings":";;;;;;AAQA,IAAI,aAAyB,EAAC;AAKvB,SAAS,cAAc,MAAA,EAA0B;AACtD,EAAA,UAAA,GAAa,EAAE,GAAG,UAAA,EAAY,GAAG,MAAA,EAAO;AAC1C;AASA,IAAM,aAAA,uBAAoB,OAAA,EAA6B;AAEhD,SAAS,iBAAA,CAAkB,KAAa,KAAA,EAAwC;AACrF,EAAA,MAAM,IAAA,GAAOA,UAAM,aAAA,EAAc;AACjC,EAAA,IAAI,CAAC,IAAA,EAAM;AAGX,EAAA,IAAA,CAAK,YAAA,CAAa,KAAK,KAAK,CAAA;AAG5B,EAAA,IAAI,WAAA,GAAc,aAAA,CAAc,GAAA,CAAI,IAAI,CAAA;AACxC,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,WAAA,uBAAkB,GAAA,EAAY;AAC9B,IAAA,aAAA,CAAc,GAAA,CAAI,MAAM,WAAW,CAAA;AAAA,EACrC;AAEA,EAAA,IAAI,CAAC,WAAA,CAAY,GAAA,CAAI,GAAG,CAAA,EAAG;AACzB,IAAA,WAAA,CAAY,IAAI,GAAG,CAAA;AAEnB,IAAA,IAAA,CAAK,YAAA,CAAaC,4BAAU,gBAAA,EAAkB,CAAC,GAAG,WAAW,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,EAC1E;AACF;AAQO,SAAS,eAAA,CAAgB,KAAa,KAAA,EAAiD;AAC5F,EAAA,MAAM,IAAA,GAAOD,UAAM,aAAA,EAAc;AACjC,EAAA,IAAI,CAAC,IAAA,EAAM;AAEX,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,YAAA,CAAa,GAAA,EAAK,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,IAC9C,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,CAAK,YAAA,CAAa,KAAK,wBAAwB,CAAA;AAAA,IACjD;AAAA,EACF,CAAA,MAAO;AACL,IAAA,IAAA,CAAK,YAAA,CAAa,KAAK,KAAK,CAAA;AAAA,EAC9B;AACF","file":"chunk-35F3UBOO.cjs","sourcesContent":["/**\n * X-Ray annotation and metadata helpers\n */\n\nimport { trace } from '@opentelemetry/api';\nimport { AWS_ATTRS } from '../attributes';\nimport type { XRayConfig } from '../config';\n\nlet xrayConfig: XRayConfig = {};\n\n/**\n * Configure X-Ray compatibility features\n */\nexport function configureXRay(config: XRayConfig): void {\n xrayConfig = { ...xrayConfig, ...config };\n}\n\n/**\n * Set X-Ray annotation (indexed in X-Ray console)\n *\n * Annotations are indexed and can be used for filtering in X-Ray.\n * They are stored as span attributes with a special annotation list.\n */\n// Track annotations per span (since we can't read attributes back from spans)\nconst annotationMap = new WeakMap<object, Set<string>>();\n\nexport function setXRayAnnotation(key: string, value: string | number | boolean): void {\n const span = trace.getActiveSpan();\n if (!span) return;\n\n // Set the attribute\n span.setAttribute(key, value);\n\n // Track annotation keys for this span\n let annotations = annotationMap.get(span);\n if (!annotations) {\n annotations = new Set<string>();\n annotationMap.set(span, annotations);\n }\n \n if (!annotations.has(key)) {\n annotations.add(key);\n // Store annotation list as comma-separated string (X-Ray format)\n span.setAttribute(AWS_ATTRS.XRAY_ANNOTATIONS, [...annotations].join(','));\n }\n}\n\n/**\n * Set X-Ray metadata (not indexed)\n *\n * Metadata is not indexed but can be viewed in X-Ray console.\n * It's stored as regular span attributes.\n */\nexport function setXRayMetadata(key: string, value: string | number | boolean | object): void {\n const span = trace.getActiveSpan();\n if (!span) return;\n\n if (typeof value === 'object') {\n try {\n span.setAttribute(key, JSON.stringify(value));\n } catch {\n span.setAttribute(key, '<serialization-failed>');\n }\n } else {\n span.setAttribute(key, value);\n }\n}\n"]}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkUZEJV2YD_cjs = require('./chunk-UZEJV2YD.cjs');
|
|
4
|
+
var chunkJEQ2X3Z6_cjs = require('./chunk-JEQ2X3Z6.cjs');
|
|
5
|
+
|
|
6
|
+
// src/sdk/auto-instrument.ts
|
|
7
|
+
var INSTRUMENTED_SYMBOL = Symbol.for("autotel-aws.instrumented");
|
|
8
|
+
var globalAutoInstrumentEnabled = false;
|
|
9
|
+
var originalSmithyClientSend = null;
|
|
10
|
+
function isInstrumented(client) {
|
|
11
|
+
return typeof client === "object" && client !== null && client[INSTRUMENTED_SYMBOL] === true;
|
|
12
|
+
}
|
|
13
|
+
function markAsInstrumented(client) {
|
|
14
|
+
client[INSTRUMENTED_SYMBOL] = true;
|
|
15
|
+
return client;
|
|
16
|
+
}
|
|
17
|
+
function instrumentSDK(client, config) {
|
|
18
|
+
if (isInstrumented(client)) {
|
|
19
|
+
return client;
|
|
20
|
+
}
|
|
21
|
+
const wrappedClient = chunkUZEJV2YD_cjs.wrapSDKClient(client, config?.service);
|
|
22
|
+
return markAsInstrumented(wrappedClient);
|
|
23
|
+
}
|
|
24
|
+
function createTracedClient(ClientClass, config) {
|
|
25
|
+
const client = new ClientClass(config);
|
|
26
|
+
return instrumentSDK(client, config);
|
|
27
|
+
}
|
|
28
|
+
function autoInstrumentAWS(config) {
|
|
29
|
+
if (globalAutoInstrumentEnabled) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
let SmithyClient;
|
|
33
|
+
try {
|
|
34
|
+
SmithyClient = chunkJEQ2X3Z6_cjs.__require("@aws-sdk/smithy-client").Client;
|
|
35
|
+
} catch {
|
|
36
|
+
try {
|
|
37
|
+
SmithyClient = chunkJEQ2X3Z6_cjs.__require("@smithy/smithy-client").Client;
|
|
38
|
+
} catch {
|
|
39
|
+
console.warn(
|
|
40
|
+
"[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."
|
|
41
|
+
);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
originalSmithyClientSend = SmithyClient.prototype.send;
|
|
46
|
+
const originalSend = SmithyClient.prototype.send;
|
|
47
|
+
SmithyClient.prototype.send = function patchedSend(command, ...args) {
|
|
48
|
+
if (isInstrumented(this)) {
|
|
49
|
+
return originalSend.call(this, command, ...args);
|
|
50
|
+
}
|
|
51
|
+
const wrappedClient = chunkUZEJV2YD_cjs.wrapSDKClient(this, config?.service);
|
|
52
|
+
return wrappedClient.send(command, ...args);
|
|
53
|
+
};
|
|
54
|
+
globalAutoInstrumentEnabled = true;
|
|
55
|
+
}
|
|
56
|
+
function disableAutoInstrumentAWS() {
|
|
57
|
+
if (!globalAutoInstrumentEnabled || !originalSmithyClientSend) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
let SmithyClient;
|
|
61
|
+
try {
|
|
62
|
+
SmithyClient = chunkJEQ2X3Z6_cjs.__require("@aws-sdk/smithy-client").Client;
|
|
63
|
+
} catch {
|
|
64
|
+
try {
|
|
65
|
+
SmithyClient = chunkJEQ2X3Z6_cjs.__require("@smithy/smithy-client").Client;
|
|
66
|
+
} catch {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
SmithyClient.prototype.send = originalSmithyClientSend;
|
|
71
|
+
originalSmithyClientSend = null;
|
|
72
|
+
globalAutoInstrumentEnabled = false;
|
|
73
|
+
}
|
|
74
|
+
function isAutoInstrumentEnabled() {
|
|
75
|
+
return globalAutoInstrumentEnabled;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
exports.autoInstrumentAWS = autoInstrumentAWS;
|
|
79
|
+
exports.createTracedClient = createTracedClient;
|
|
80
|
+
exports.disableAutoInstrumentAWS = disableAutoInstrumentAWS;
|
|
81
|
+
exports.instrumentSDK = instrumentSDK;
|
|
82
|
+
exports.isAutoInstrumentEnabled = isAutoInstrumentEnabled;
|
|
83
|
+
//# sourceMappingURL=chunk-4TGVGEUN.cjs.map
|
|
84
|
+
//# sourceMappingURL=chunk-4TGVGEUN.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sdk/auto-instrument.ts"],"names":["wrapSDKClient","__require"],"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,GAAgBA,+BAAA,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,GAAeC,2BAAA,CAAQ,wBAAwB,CAAA,CAAE,MAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AAEN,IAAA,IAAI;AAEF,MAAA,YAAA,GAAeA,2BAAA,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,GAAgBD,+BAAA,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,GAAeC,2BAAA,CAAQ,wBAAwB,CAAA,CAAE,MAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AACN,IAAA,IAAI;AAEF,MAAA,YAAA,GAAeA,2BAAA,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-4TGVGEUN.cjs","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"]}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { wrapSDKClient } from './chunk-YG56NRIO.js';
|
|
2
|
+
import { buildSNSAttributes } from './chunk-I4CKQ4RD.js';
|
|
3
|
+
import { trace } from 'autotel';
|
|
4
|
+
import { propagation, context, SpanStatusCode } from '@opentelemetry/api';
|
|
5
|
+
|
|
6
|
+
function traceSNS(config) {
|
|
7
|
+
const operation = config.operation ?? "publish";
|
|
8
|
+
return function wrapper(fn) {
|
|
9
|
+
return trace(
|
|
10
|
+
`sns.${operation}`,
|
|
11
|
+
(ctx) => async (...args) => {
|
|
12
|
+
ctx.setAttributes(buildSNSAttributes({ topicArn: config.topicArn }));
|
|
13
|
+
const handler = fn(ctx);
|
|
14
|
+
return handler(...args);
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
var SNSPublisher = class {
|
|
20
|
+
client;
|
|
21
|
+
config;
|
|
22
|
+
topicName;
|
|
23
|
+
constructor(client, config) {
|
|
24
|
+
this.client = wrapSDKClient(client, config.service);
|
|
25
|
+
this.config = {
|
|
26
|
+
injectTraceContext: true,
|
|
27
|
+
...config
|
|
28
|
+
};
|
|
29
|
+
this.topicName = config.topicArn.split(":").pop() || "unknown";
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Inject trace context into message attributes
|
|
33
|
+
*/
|
|
34
|
+
injectContext(attributes) {
|
|
35
|
+
if (!this.config.injectTraceContext) {
|
|
36
|
+
return attributes || {};
|
|
37
|
+
}
|
|
38
|
+
const carrier = {};
|
|
39
|
+
propagation.inject(context.active(), carrier);
|
|
40
|
+
const result = { ...attributes };
|
|
41
|
+
if (carrier.traceparent) {
|
|
42
|
+
result.traceparent = { StringValue: carrier.traceparent, DataType: "String" };
|
|
43
|
+
}
|
|
44
|
+
if (carrier.tracestate) {
|
|
45
|
+
result.tracestate = { StringValue: carrier.tracestate, DataType: "String" };
|
|
46
|
+
}
|
|
47
|
+
if (carrier.baggage) {
|
|
48
|
+
result.baggage = { StringValue: carrier.baggage, DataType: "String" };
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Publish a message to the topic
|
|
54
|
+
*
|
|
55
|
+
* @param message - Message to publish
|
|
56
|
+
* @returns Promise with message ID and sequence number
|
|
57
|
+
*/
|
|
58
|
+
async publish(message) {
|
|
59
|
+
return trace(`sns.publish`, async (ctx) => {
|
|
60
|
+
ctx.setAttributes(buildSNSAttributes({ topicArn: this.config.topicArn }));
|
|
61
|
+
ctx.setAttribute("messaging.destination.name", this.topicName);
|
|
62
|
+
const input = {
|
|
63
|
+
TopicArn: message.targetArn ? void 0 : this.config.topicArn,
|
|
64
|
+
TargetArn: message.targetArn,
|
|
65
|
+
PhoneNumber: message.phoneNumber,
|
|
66
|
+
Message: message.message,
|
|
67
|
+
Subject: message.subject,
|
|
68
|
+
MessageAttributes: this.injectContext(message.attributes),
|
|
69
|
+
MessageStructure: message.messageStructure,
|
|
70
|
+
...message.messageGroupId && { MessageGroupId: message.messageGroupId },
|
|
71
|
+
...message.messageDeduplicationId && {
|
|
72
|
+
MessageDeduplicationId: message.messageDeduplicationId
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
try {
|
|
76
|
+
const { PublishCommand } = await import('@aws-sdk/client-sns');
|
|
77
|
+
const result = await this.client.send(new PublishCommand(input));
|
|
78
|
+
if (result.MessageId) {
|
|
79
|
+
ctx.setAttribute("messaging.message.id", result.MessageId);
|
|
80
|
+
}
|
|
81
|
+
ctx.setStatus({ code: SpanStatusCode.OK });
|
|
82
|
+
return {
|
|
83
|
+
messageId: result.MessageId,
|
|
84
|
+
sequenceNumber: result.SequenceNumber
|
|
85
|
+
};
|
|
86
|
+
} catch (error) {
|
|
87
|
+
ctx.setStatus({
|
|
88
|
+
code: SpanStatusCode.ERROR,
|
|
89
|
+
message: error instanceof Error ? error.message : "Publish failed"
|
|
90
|
+
});
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Publish multiple messages in a batch
|
|
97
|
+
*
|
|
98
|
+
* @param messages - Array of messages to publish (max 10)
|
|
99
|
+
* @returns Promise with successful and failed message results
|
|
100
|
+
*/
|
|
101
|
+
async publishBatch(messages) {
|
|
102
|
+
return trace(`sns.publishBatch`, async (ctx) => {
|
|
103
|
+
ctx.setAttributes(buildSNSAttributes({ topicArn: this.config.topicArn }));
|
|
104
|
+
ctx.setAttribute("messaging.batch.message_count", messages.length);
|
|
105
|
+
const entries = messages.map((msg, index) => ({
|
|
106
|
+
Id: String(index),
|
|
107
|
+
Message: msg.message,
|
|
108
|
+
Subject: msg.subject,
|
|
109
|
+
MessageAttributes: this.injectContext(msg.attributes),
|
|
110
|
+
MessageStructure: msg.messageStructure,
|
|
111
|
+
...msg.messageGroupId && { MessageGroupId: msg.messageGroupId },
|
|
112
|
+
...msg.messageDeduplicationId && {
|
|
113
|
+
MessageDeduplicationId: msg.messageDeduplicationId
|
|
114
|
+
}
|
|
115
|
+
}));
|
|
116
|
+
try {
|
|
117
|
+
const { PublishBatchCommand } = await import('@aws-sdk/client-sns');
|
|
118
|
+
const result = await this.client.send(
|
|
119
|
+
new PublishBatchCommand({
|
|
120
|
+
TopicArn: this.config.topicArn,
|
|
121
|
+
PublishBatchRequestEntries: entries
|
|
122
|
+
})
|
|
123
|
+
);
|
|
124
|
+
const successful = result.Successful?.map((s) => ({
|
|
125
|
+
id: s.Id,
|
|
126
|
+
messageId: s.MessageId,
|
|
127
|
+
sequenceNumber: s.SequenceNumber
|
|
128
|
+
})) || [];
|
|
129
|
+
const failed = result.Failed?.map((f) => ({
|
|
130
|
+
id: f.Id,
|
|
131
|
+
code: f.Code,
|
|
132
|
+
message: f.Message
|
|
133
|
+
})) || [];
|
|
134
|
+
ctx.setAttribute("messaging.sns.successful_count", successful.length);
|
|
135
|
+
ctx.setAttribute("messaging.sns.failed_count", failed.length);
|
|
136
|
+
if (failed.length > 0) {
|
|
137
|
+
ctx.setStatus({
|
|
138
|
+
code: SpanStatusCode.ERROR,
|
|
139
|
+
message: `${failed.length} messages failed`
|
|
140
|
+
});
|
|
141
|
+
} else {
|
|
142
|
+
ctx.setStatus({ code: SpanStatusCode.OK });
|
|
143
|
+
}
|
|
144
|
+
return { successful, failed };
|
|
145
|
+
} catch (error) {
|
|
146
|
+
ctx.setStatus({
|
|
147
|
+
code: SpanStatusCode.ERROR,
|
|
148
|
+
message: error instanceof Error ? error.message : "Batch publish failed"
|
|
149
|
+
});
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Publish to a specific endpoint (mobile push, etc.)
|
|
156
|
+
*
|
|
157
|
+
* @param message - Message with targetArn set
|
|
158
|
+
* @returns Promise with message ID
|
|
159
|
+
*/
|
|
160
|
+
async publishToEndpoint(message) {
|
|
161
|
+
return trace(`sns.publishToEndpoint`, async (ctx) => {
|
|
162
|
+
ctx.setAttribute("messaging.system", "aws_sns");
|
|
163
|
+
ctx.setAttribute("aws.sns.target_arn", message.targetArn);
|
|
164
|
+
const input = {
|
|
165
|
+
TargetArn: message.targetArn,
|
|
166
|
+
Message: message.message,
|
|
167
|
+
Subject: message.subject,
|
|
168
|
+
MessageAttributes: this.injectContext(message.attributes),
|
|
169
|
+
MessageStructure: message.messageStructure
|
|
170
|
+
};
|
|
171
|
+
try {
|
|
172
|
+
const { PublishCommand } = await import('@aws-sdk/client-sns');
|
|
173
|
+
const result = await this.client.send(new PublishCommand(input));
|
|
174
|
+
if (result.MessageId) {
|
|
175
|
+
ctx.setAttribute("messaging.message.id", result.MessageId);
|
|
176
|
+
}
|
|
177
|
+
ctx.setStatus({ code: SpanStatusCode.OK });
|
|
178
|
+
return { messageId: result.MessageId };
|
|
179
|
+
} catch (error) {
|
|
180
|
+
ctx.setStatus({
|
|
181
|
+
code: SpanStatusCode.ERROR,
|
|
182
|
+
message: error instanceof Error ? error.message : "Endpoint publish failed"
|
|
183
|
+
});
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
export { SNSPublisher, traceSNS };
|
|
191
|
+
//# sourceMappingURL=chunk-CIGXV6HA.js.map
|
|
192
|
+
//# sourceMappingURL=chunk-CIGXV6HA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sns/index.ts"],"names":[],"mappings":"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","file":"chunk-CIGXV6HA.js","sourcesContent":["/**\n * SNS-specific instrumentation\n *\n * Provides semantic helpers for tracing SNS operations with proper OpenTelemetry\n * messaging semantic conventions. Automatically sets `messaging.*` attributes.\n *\n * @example Publish to topic\n * ```typescript\n * import { traceSNS } from 'autotel-aws/sns';\n * import { SNSClient, PublishCommand } from '@aws-sdk/client-sns';\n *\n * const sns = new SNSClient({});\n *\n * export const publishNotification = traceSNS({\n * topicArn: 'arn:aws:sns:us-east-1:123456789:notifications'\n * })(ctx => async (message: string, subject?: string) => {\n * const result = await sns.send(new PublishCommand({\n * TopicArn: 'arn:aws:sns:us-east-1:123456789:notifications',\n * Message: message,\n * Subject: subject\n * }));\n *\n * if (result.MessageId) {\n * ctx.setAttribute('messaging.message.id', result.MessageId);\n * }\n *\n * return result;\n * });\n *\n * // Usage: await publishNotification('User signed up', 'New User');\n * ```\n *\n * @example Publish to mobile endpoint\n * ```typescript\n * export const sendPushNotification = traceSNS({\n * operation: 'publish',\n * topicArn: 'arn:aws:sns:us-east-1:123456789:app/APNS/my-app'\n * })(ctx => async (endpointArn: string, payload: object) => {\n * ctx.setAttribute('aws.sns.target_arn', endpointArn);\n * return await sns.send(new PublishCommand({\n * TargetArn: endpointArn,\n * Message: JSON.stringify(payload),\n * MessageStructure: 'json'\n * }));\n * });\n * ```\n */\n\nimport { trace, type TraceContext } from 'autotel';\nimport { context, propagation, SpanStatusCode } from '@opentelemetry/api';\nimport { buildSNSAttributes } from '../attributes';\nimport { wrapSDKClient } from '../common/sdk-wrapper';\n\n/**\n * SNS operation configuration\n */\nexport interface TraceSNSConfig {\n /**\n * SNS topic ARN\n * Sets `messaging.destination.name` attribute.\n */\n topicArn: string;\n\n /**\n * Operation type (defaults to 'publish')\n */\n operation?: 'publish' | 'subscribe' | 'unsubscribe';\n}\n\n/**\n * Trace SNS operations with semantic attributes\n *\n * Creates a traced function that automatically sets SNS messaging semantic attributes\n * following OpenTelemetry conventions.\n *\n * @param config - SNS operation configuration\n * @returns A higher-order function that wraps your SNS operation with tracing\n *\n * @remarks\n * Semantic attributes set automatically:\n * - `messaging.system` - 'aws_sns'\n * - `messaging.destination.name` - Topic ARN\n * - `messaging.operation` - 'publish'\n *\n * Additional attributes you should set in your handler:\n * - `messaging.message.id` - Message ID from response\n * - `aws.sns.target_arn` - Target ARN for direct publishing\n *\n * @see https://opentelemetry.io/docs/specs/semconv/messaging/aws-sns/\n */\nexport function traceSNS(config: TraceSNSConfig) {\n const operation = config.operation ?? 'publish';\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 `sns.${operation}`,\n (ctx: TraceContext) =>\n async (...args: TArgs): Promise<TReturn> => {\n // Set SNS semantic attributes\n ctx.setAttributes(buildSNSAttributes({ topicArn: config.topicArn }));\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// SNS Publisher - Publishes messages with automatic trace context injection\n// ============================================================================\n\n/**\n * Configuration for SNS Publisher\n */\nexport interface SNSPublisherConfig {\n /**\n * SNS Topic ARN\n */\n topicArn: string;\n\n /**\n * Inject W3C Trace Context into message attributes\n * Enables distributed tracing to SNS subscribers (e.g., Lambda, SQS)\n * @default true\n */\n injectTraceContext?: boolean;\n\n /**\n * Optional service name for tracing\n */\n service?: string;\n}\n\n/**\n * Message to publish via SNS Publisher\n */\nexport interface SNSPublishMessage {\n /**\n * Message body (string or JSON for message structure)\n */\n message: string;\n\n /**\n * Optional subject (for email/SMS subscriptions)\n */\n subject?: string;\n\n /**\n * Optional message attributes\n */\n attributes?: Record<string, { StringValue: string; DataType: string }>;\n\n /**\n * Optional target ARN for direct endpoint publishing\n */\n targetArn?: string;\n\n /**\n * Optional phone number for SMS\n */\n phoneNumber?: string;\n\n /**\n * Optional message structure ('json' for platform-specific messages)\n */\n messageStructure?: 'json';\n\n /**\n * Optional message group ID (for FIFO topics)\n */\n messageGroupId?: string;\n\n /**\n * Optional deduplication ID (for FIFO topics)\n */\n messageDeduplicationId?: string;\n}\n\n/**\n * SNS Publisher with automatic trace context injection\n *\n * Wraps an SNS client to automatically:\n * - Create spans for publish operations\n * - Inject W3C Trace Context into message attributes\n * - Set proper semantic attributes\n *\n * @example Basic usage\n * ```typescript\n * import { SNSPublisher } from 'autotel-aws/sns';\n * import { SNSClient } from '@aws-sdk/client-sns';\n *\n * const sns = new SNSClient({ region: 'us-east-1' });\n * const publisher = new SNSPublisher(sns, {\n * topicArn: 'arn:aws:sns:us-east-1:123456789:my-topic'\n * });\n *\n * // Publish with automatic trace context\n * const result = await publisher.publish({\n * message: 'Order completed',\n * subject: 'Order #12345'\n * });\n * console.log('Message ID:', result.messageId);\n * ```\n *\n * @example With custom attributes\n * ```typescript\n * await publisher.publish({\n * message: JSON.stringify({ orderId: '12345', status: 'completed' }),\n * attributes: {\n * 'eventType': { StringValue: 'ORDER_COMPLETED', DataType: 'String' },\n * 'priority': { StringValue: 'high', DataType: 'String' }\n * }\n * });\n * ```\n *\n * @example Batch publish\n * ```typescript\n * const results = await publisher.publishBatch([\n * { message: 'Event 1' },\n * { message: 'Event 2' },\n * { message: 'Event 3' }\n * ]);\n * console.log(`Published ${results.successful.length} messages`);\n * ```\n *\n * @example Direct endpoint publish\n * ```typescript\n * await publisher.publishToEndpoint({\n * targetArn: 'arn:aws:sns:us-east-1:123456789:endpoint/APNS/my-app/device-token',\n * message: JSON.stringify({\n * APNS: JSON.stringify({ aps: { alert: 'Hello!' } })\n * }),\n * messageStructure: 'json'\n * });\n * ```\n */\nexport class SNSPublisher<\n \n TClient extends { send: (command: any) => Promise<any> } = any,\n> {\n private client: TClient;\n private config: Required<Pick<SNSPublisherConfig, 'topicArn'>> & SNSPublisherConfig;\n private topicName: string;\n\n constructor(client: TClient, config: SNSPublisherConfig) {\n this.client = wrapSDKClient(client as any, config.service) as TClient;\n this.config = {\n injectTraceContext: true,\n ...config,\n };\n // Extract topic name from ARN (last segment)\n this.topicName = config.topicArn.split(':').pop() || 'unknown';\n }\n\n /**\n * Inject trace context into message attributes\n */\n private injectContext(\n attributes?: Record<string, { StringValue: string; DataType: string }>,\n ): Record<string, { StringValue: string; DataType: string }> {\n if (!this.config.injectTraceContext) {\n return attributes || {};\n }\n\n const carrier: Record<string, string> = {};\n propagation.inject(context.active(), carrier);\n\n const result = { ...attributes };\n\n if (carrier.traceparent) {\n result.traceparent = { StringValue: carrier.traceparent, DataType: 'String' };\n }\n if (carrier.tracestate) {\n result.tracestate = { StringValue: carrier.tracestate, DataType: 'String' };\n }\n if (carrier.baggage) {\n result.baggage = { StringValue: carrier.baggage, DataType: 'String' };\n }\n\n return result;\n }\n\n /**\n * Publish a message to the topic\n *\n * @param message - Message to publish\n * @returns Promise with message ID and sequence number\n */\n async publish(message: SNSPublishMessage): Promise<{\n messageId?: string;\n sequenceNumber?: string;\n }> {\n return trace(`sns.publish`, async (ctx: TraceContext) => {\n ctx.setAttributes(buildSNSAttributes({ topicArn: this.config.topicArn }));\n ctx.setAttribute('messaging.destination.name', this.topicName);\n\n const input = {\n TopicArn: message.targetArn ? undefined : this.config.topicArn,\n TargetArn: message.targetArn,\n PhoneNumber: message.phoneNumber,\n Message: message.message,\n Subject: message.subject,\n MessageAttributes: this.injectContext(message.attributes),\n MessageStructure: message.messageStructure,\n ...(message.messageGroupId && { MessageGroupId: message.messageGroupId }),\n ...(message.messageDeduplicationId && {\n MessageDeduplicationId: message.messageDeduplicationId,\n }),\n };\n\n try {\n const { PublishCommand } = await import('@aws-sdk/client-sns');\n const result = await this.client.send(new PublishCommand(input));\n\n if (result.MessageId) {\n ctx.setAttribute('messaging.message.id', result.MessageId);\n }\n\n ctx.setStatus({ code: SpanStatusCode.OK });\n\n return {\n messageId: result.MessageId,\n sequenceNumber: result.SequenceNumber,\n };\n } catch (error) {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'Publish failed',\n });\n throw error;\n }\n });\n }\n\n /**\n * Publish multiple messages in a batch\n *\n * @param messages - Array of messages to publish (max 10)\n * @returns Promise with successful and failed message results\n */\n async publishBatch(messages: SNSPublishMessage[]): Promise<{\n successful: Array<{ id: string; messageId?: string; sequenceNumber?: string }>;\n failed: Array<{ id: string; code?: string; message?: string }>;\n }> {\n return trace(`sns.publishBatch`, async (ctx: TraceContext) => {\n ctx.setAttributes(buildSNSAttributes({ topicArn: this.config.topicArn }));\n ctx.setAttribute('messaging.batch.message_count', messages.length);\n\n const entries = messages.map((msg, index) => ({\n Id: String(index),\n Message: msg.message,\n Subject: msg.subject,\n MessageAttributes: this.injectContext(msg.attributes),\n MessageStructure: msg.messageStructure,\n ...(msg.messageGroupId && { MessageGroupId: msg.messageGroupId }),\n ...(msg.messageDeduplicationId && {\n MessageDeduplicationId: msg.messageDeduplicationId,\n }),\n }));\n\n try {\n const { PublishBatchCommand } = await import('@aws-sdk/client-sns');\n const result = await this.client.send(\n new PublishBatchCommand({\n TopicArn: this.config.topicArn,\n PublishBatchRequestEntries: entries,\n }),\n );\n\n const successful =\n result.Successful?.map((s: { Id?: string; MessageId?: string; SequenceNumber?: string }) => ({\n id: s.Id!,\n messageId: s.MessageId,\n sequenceNumber: s.SequenceNumber,\n })) || [];\n\n const failed =\n result.Failed?.map((f: { Id?: string; Code?: string; Message?: string }) => ({\n id: f.Id!,\n code: f.Code,\n message: f.Message,\n })) || [];\n\n ctx.setAttribute('messaging.sns.successful_count', successful.length);\n ctx.setAttribute('messaging.sns.failed_count', failed.length);\n\n if (failed.length > 0) {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: `${failed.length} messages failed`,\n });\n } else {\n ctx.setStatus({ code: SpanStatusCode.OK });\n }\n\n return { successful, failed };\n } catch (error) {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'Batch publish failed',\n });\n throw error;\n }\n });\n }\n\n /**\n * Publish to a specific endpoint (mobile push, etc.)\n *\n * @param message - Message with targetArn set\n * @returns Promise with message ID\n */\n async publishToEndpoint(\n message: Omit<SNSPublishMessage, 'targetArn'> & { targetArn: string },\n ): Promise<{ messageId?: string }> {\n return trace(`sns.publishToEndpoint`, async (ctx: TraceContext) => {\n ctx.setAttribute('messaging.system', 'aws_sns');\n ctx.setAttribute('aws.sns.target_arn', message.targetArn);\n\n const input = {\n TargetArn: message.targetArn,\n Message: message.message,\n Subject: message.subject,\n MessageAttributes: this.injectContext(message.attributes),\n MessageStructure: message.messageStructure,\n };\n\n try {\n const { PublishCommand } = await import('@aws-sdk/client-sns');\n const result = await this.client.send(new PublishCommand(input));\n\n if (result.MessageId) {\n ctx.setAttribute('messaging.message.id', result.MessageId);\n }\n\n ctx.setStatus({ code: SpanStatusCode.OK });\n\n return { messageId: result.MessageId };\n } catch (error) {\n ctx.setStatus({\n code: SpanStatusCode.ERROR,\n message: error instanceof Error ? error.message : 'Endpoint publish failed',\n });\n throw error;\n }\n });\n }\n}\n"]}
|