autotel-aws 0.13.15 → 0.13.17
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/package.json +4 -3
- package/skills/autotel-aws/SKILL.md +242 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel-aws",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.17",
|
|
4
4
|
"description": "OpenTelemetry instrumentation for AWS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -89,7 +89,8 @@
|
|
|
89
89
|
"types": "./dist/index.d.ts",
|
|
90
90
|
"files": [
|
|
91
91
|
"dist",
|
|
92
|
-
"README.md"
|
|
92
|
+
"README.md",
|
|
93
|
+
"skills"
|
|
93
94
|
],
|
|
94
95
|
"keywords": [
|
|
95
96
|
"opentelemetry",
|
|
@@ -184,7 +185,7 @@
|
|
|
184
185
|
"@opentelemetry/semantic-conventions": "^1.41.1",
|
|
185
186
|
"@opentelemetry/propagator-aws-xray": "^2.2.0",
|
|
186
187
|
"@types/aws-lambda": "^8.10.162",
|
|
187
|
-
"autotel": "4.
|
|
188
|
+
"autotel": "4.1.0"
|
|
188
189
|
},
|
|
189
190
|
"devDependencies": {
|
|
190
191
|
"@aws-sdk/client-s3": "^3.1063.0",
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: autotel-aws
|
|
3
|
+
description: >
|
|
4
|
+
OpenTelemetry instrumentation for AWS services (Lambda, SDK v3 clients, S3, DynamoDB, SQS, SNS, Kinesis, Step Functions, X-Ray) built on top of autotel.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# autotel-aws
|
|
8
|
+
|
|
9
|
+
Vendor-agnostic OpenTelemetry instrumentation for AWS. Works with any OTLP backend. Provides:
|
|
10
|
+
|
|
11
|
+
- Lambda handler wrapping with automatic cold-start detection, trigger-type detection, and distributed trace context extraction
|
|
12
|
+
- AWS SDK v3 auto-instrumentation (per-client, pre-built, or global)
|
|
13
|
+
- Service-specific semantic helpers following OTel semantic conventions: S3, DynamoDB, SQS, SNS, Kinesis, Step Functions
|
|
14
|
+
- X-Ray compatibility layer (propagator, ID generator)
|
|
15
|
+
- AWS resource detectors (EC2, ECS, EKS)
|
|
16
|
+
|
|
17
|
+
## Setup
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add autotel-aws autotel
|
|
21
|
+
# Add only the AWS SDK clients you actually use
|
|
22
|
+
pnpm add @aws-sdk/client-s3 @aws-sdk/client-dynamodb
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Initialize at the top of your entry point (before any handlers or SDK usage):
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { init } from 'autotel-aws';
|
|
29
|
+
|
|
30
|
+
await init({
|
|
31
|
+
service: 'my-service',
|
|
32
|
+
endpoint: process.env.OTLP_ENDPOINT,
|
|
33
|
+
region: process.env.AWS_REGION,
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`init` delegates to `autotel`'s `init()` and sets `cloud.provider: 'aws'` and `cloud.region` automatically.
|
|
38
|
+
|
|
39
|
+
## Configuration / Core Patterns
|
|
40
|
+
|
|
41
|
+
### Lambda handler instrumentation
|
|
42
|
+
|
|
43
|
+
**Simple wrap (no trace context access):**
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { wrapHandler } from 'autotel-aws/lambda';
|
|
47
|
+
|
|
48
|
+
export const handler = wrapHandler(async (event, context) => {
|
|
49
|
+
return { statusCode: 200, body: JSON.stringify({ ok: true }) };
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Automatically sets: `faas.name`, `faas.version`, `faas.invocation_id`, `faas.coldstart`, `faas.trigger`, `cloud.provider`, `cloud.region`, `cloud.account.id`.
|
|
54
|
+
|
|
55
|
+
**With trace context access (`traceLambda`):**
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { traceLambda } from 'autotel-aws/lambda';
|
|
59
|
+
|
|
60
|
+
export const handler = traceLambda((ctx) => async (event, lambdaContext) => {
|
|
61
|
+
ctx.setAttribute('user.id', event.userId);
|
|
62
|
+
const result = await processOrder(event);
|
|
63
|
+
ctx.setAttribute('order.status', result.status);
|
|
64
|
+
return { statusCode: 200 };
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**LambdaInstrumentationConfig options:**
|
|
69
|
+
|
|
70
|
+
| Option | Default | Description |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `captureResponse` | `false` | Serialise response into `lambda.response` attribute (capped at 4 096 bytes) |
|
|
73
|
+
| `extractTraceContext` | `true` | Extract W3C / X-Ray trace context from the incoming event |
|
|
74
|
+
| `service` | — | Override service name |
|
|
75
|
+
|
|
76
|
+
### AWS SDK v3 instrumentation
|
|
77
|
+
|
|
78
|
+
Three approaches — pick one:
|
|
79
|
+
|
|
80
|
+
**A. Instrument an existing client:**
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { instrumentSDK } from 'autotel-aws/sdk';
|
|
84
|
+
import { S3Client } from '@aws-sdk/client-s3';
|
|
85
|
+
|
|
86
|
+
const s3 = instrumentSDK(new S3Client({ region: 'us-east-1' }));
|
|
87
|
+
// All s3.send() calls are now traced automatically
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**B. Create a pre-instrumented client:**
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { createTracedClient } from 'autotel-aws/sdk';
|
|
94
|
+
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
|
95
|
+
|
|
96
|
+
const dynamo = createTracedClient(DynamoDBClient, { region: 'us-east-1' });
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**C. Global auto-instrumentation (call once at startup):**
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { autoInstrumentAWS } from 'autotel-aws/sdk';
|
|
103
|
+
|
|
104
|
+
autoInstrumentAWS();
|
|
105
|
+
|
|
106
|
+
// All subsequently created clients are instrumented automatically
|
|
107
|
+
const s3 = new S3Client({});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Disable with `disableAutoInstrumentAWS()`. Check status with `isAutoInstrumentEnabled()`.
|
|
111
|
+
|
|
112
|
+
### Service-specific semantic tracing helpers
|
|
113
|
+
|
|
114
|
+
All service helpers follow the same curried factory pattern:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
traceXxx(config)(ctx => async (...args) => { ... })
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**S3:**
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { traceS3 } from 'autotel-aws/s3';
|
|
124
|
+
|
|
125
|
+
const getFile = traceS3({ operation: 'GetObject', bucket: 'my-bucket' })(
|
|
126
|
+
(ctx) => async (key: string) => {
|
|
127
|
+
ctx.setAttribute('aws.s3.key', key);
|
|
128
|
+
return await s3.send(new GetObjectCommand({ Bucket: 'my-bucket', Key: key }));
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
await getFile('path/to/file.txt');
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Auto-sets: `aws.s3.bucket`. Span name: `s3.GetObject`.
|
|
136
|
+
|
|
137
|
+
**DynamoDB:**
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import { traceDynamoDB } from 'autotel-aws/dynamodb';
|
|
141
|
+
|
|
142
|
+
const getUser = traceDynamoDB({ operation: 'GetItem', table: 'users' })(
|
|
143
|
+
(ctx) => async (userId: string) => {
|
|
144
|
+
ctx.setAttribute('db.statement', 'GetItem WHERE id = :id');
|
|
145
|
+
const result = await dynamodb.send(new GetItemCommand({
|
|
146
|
+
TableName: 'users',
|
|
147
|
+
Key: { id: { S: userId } },
|
|
148
|
+
}));
|
|
149
|
+
if (result.ConsumedCapacity?.CapacityUnits) {
|
|
150
|
+
ctx.setAttribute('aws.dynamodb.consumed_capacity', result.ConsumedCapacity.CapacityUnits);
|
|
151
|
+
}
|
|
152
|
+
return result.Item;
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Auto-sets: `db.system` ('dynamodb'), `db.operation`, `db.name`, `aws.dynamodb.table_names`. Span name: `dynamodb.GetItem`.
|
|
158
|
+
|
|
159
|
+
**SQS / SNS / Kinesis / Step Functions / EventBridge** — follow the same `traceXxx({ operation, ... })` pattern via their respective subpaths (`autotel-aws/sqs`, `autotel-aws/sns`, etc.).
|
|
160
|
+
|
|
161
|
+
### X-Ray compatibility
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
import { configureXRay } from 'autotel-aws/xray';
|
|
165
|
+
|
|
166
|
+
// Enable X-Ray propagator and ID generator before init()
|
|
167
|
+
configureXRay({ propagator: true, idGenerator: true });
|
|
168
|
+
|
|
169
|
+
await init({ service: 'my-service' });
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### AWS resource detectors
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { getAWSResourceDetectors } from 'autotel-aws';
|
|
176
|
+
|
|
177
|
+
const detectors = await getAWSResourceDetectors();
|
|
178
|
+
// detectors = [awsEc2Detector, awsEcsDetector, awsEksDetector] if
|
|
179
|
+
// @opentelemetry/resource-detector-aws is installed; [] otherwise
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Common Mistakes
|
|
183
|
+
|
|
184
|
+
### HIGH — Calling init() after creating SDK clients
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
// WRONG: SDK clients created before SDK is initialised
|
|
188
|
+
import { S3Client } from '@aws-sdk/client-s3';
|
|
189
|
+
const s3 = new S3Client({});
|
|
190
|
+
await init({ service: 'my-service' }); // too late
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// CORRECT: init() first, clients after
|
|
195
|
+
await init({ service: 'my-service' });
|
|
196
|
+
const s3 = instrumentSDK(new S3Client({}));
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### HIGH — Using traceLambda but forgetting to call the inner handler
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
// WRONG: factory must return an async function; the function is what gets invoked
|
|
203
|
+
export const handler = traceLambda((ctx) => {
|
|
204
|
+
ctx.setAttribute('foo', 'bar'); // ctx.setAttribute called eagerly — wrong timing
|
|
205
|
+
return { statusCode: 200 }; // returning a value, not a handler function
|
|
206
|
+
});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
// CORRECT: the factory returns the handler function
|
|
211
|
+
export const handler = traceLambda((ctx) => async (event, lambdaContext) => {
|
|
212
|
+
ctx.setAttribute('foo', 'bar');
|
|
213
|
+
return { statusCode: 200 };
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### MEDIUM — Forgetting to await init() before the first invocation
|
|
218
|
+
|
|
219
|
+
Lambda cold start code runs synchronously before the handler. If `init()` is not awaited, the first invocation may execute before the SDK is ready.
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// WRONG (at module level, unawaited)
|
|
223
|
+
init({ service: 'my-service' }); // returns a Promise, not awaited
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
// CORRECT: await at module level using top-level await, or guard the handler
|
|
228
|
+
await init({ service: 'my-service' });
|
|
229
|
+
export const handler = wrapHandler(async (event) => { ... });
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### MEDIUM — Enabling captureResponse on large payloads
|
|
233
|
+
|
|
234
|
+
`captureResponse: true` serialises the full response to a span attribute. Payloads over 4 096 bytes are replaced with `lambda.response.truncated = true` and `lambda.response.size`, but the serialisation still happens. Avoid on high-throughput or large-payload handlers.
|
|
235
|
+
|
|
236
|
+
### MEDIUM — Using global autoInstrumentAWS() in tests
|
|
237
|
+
|
|
238
|
+
`autoInstrumentAWS()` patches the SDK globally and persists across test files. Always call `disableAutoInstrumentAWS()` in test teardown, or prefer `instrumentSDK()` / `createTracedClient()` for isolated instrumentation.
|
|
239
|
+
|
|
240
|
+
## Version
|
|
241
|
+
|
|
242
|
+
Targets autotel-aws v0.12.4. AWS SDK v3 peer deps: `@aws-sdk/client-*` ^3.1014.0 (all optional). Requires `autotel` as a direct dependency. See also: `autotel-backends` (vendor configs), `autotel-adapters` (HTTP framework adapters).
|