一键导入
autotel-aws
OpenTelemetry instrumentation for AWS services (Lambda, SDK v3 clients, S3, DynamoDB, SQS, SNS, Kinesis, Step Functions, X-Ray) built on top of autotel.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
OpenTelemetry instrumentation for AWS services (Lambda, SDK v3 clients, S3, DynamoDB, SQS, SNS, Kinesis, Step Functions, X-Ray) built on top of autotel.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use this skill when instrumenting AI/LLM/agent code with OpenTelemetry GenAI semantic conventions — traceGenAI() spans, token usage and cost, gen_ai.* attributes, GenAI metric views, content/evaluation events, the Vercel AI SDK bridge, or the agent identity/delegation/policy/audit governance layer. This is the canonical home for everything GenAI in autotel (the core `autotel` package is AI-free).
Review TypeScript/JavaScript code for OpenTelemetry instrumentation patterns and guide adoption of autotel. Covers Next.js, Nuxt, Nitro, TanStack Start, SvelteKit, NestJS, Express, Hono, Fastify, Elysia, Cloudflare Workers, AWS Lambda, edge runtimes, and standalone Node. Detects unstructured tracing, missing span attributes, manual exporter setup, broken context propagation, exposed PII, and ad-hoc error handling. Covers spans, metrics, logs, structured errors, the autotel processor pipeline (tail-sampling, attribute redaction, span-name normalisation, filtering, baggage), built-in enrichers (user agent, geo, request size) and custom `defineEnricher`, `defineWorkerFetch` for Cloudflare async drains, multi-vendor OTLP backends (Honeycomb, Datadog, Grafana Cloud, Sentry, Axiom, HyperDX), `composeSpanProcessors` / `composeSubscribers` / `composePostProcessors` for pipelines, AI SDK observability with gen-ai semantic conventions, and end-to-end OTLP testing.
Query OpenTelemetry telemetry (traces, metrics, logs, LLM analytics) via the autotel CLI. Use when the user asks about a production issue, slow request, error spike, expensive LLM call, or any "what is happening in my service" question. Each command returns one JSON document on stdout — parse it and answer from the data.
OpenTelemetry instrumentation for MCP (Model Context Protocol). instrumentMCPServer, instrumentMCPClient; W3C trace context via _meta; tools, resources, prompts. Security observability: annotation hints, payload-size & char-budget signals, pluggable prompt-injection classifier, spotlighting.
When to use trace vs span vs request logger vs events in Autotel. Init once at startup, package exports (autotel, autotel/event, autotel/testing). Use for setup and choosing the right API.
trace(), span(), instrument(), init(). Factory vs direct pattern, name inference. Sync init; use node-require for optional deps. Load when wrapping handlers or functions with spans.
| name | autotel-aws |
| description | OpenTelemetry instrumentation for AWS services (Lambda, SDK v3 clients, S3, DynamoDB, SQS, SNS, Kinesis, Step Functions, X-Ray) built on top of autotel. |
Vendor-agnostic OpenTelemetry instrumentation for AWS. Works with any OTLP backend. Provides:
pnpm add autotel-aws autotel
# Add only the AWS SDK clients you actually use
pnpm add @aws-sdk/client-s3 @aws-sdk/client-dynamodb
Initialize at the top of your entry point (before any handlers or SDK usage):
import { init } from 'autotel-aws';
await init({
service: 'my-service',
endpoint: process.env.OTLP_ENDPOINT,
region: process.env.AWS_REGION,
});
init delegates to autotel's init() and sets cloud.provider: 'aws' and cloud.region automatically.
Simple wrap (no trace context access):
import { wrapHandler } from 'autotel-aws/lambda';
export const handler = wrapHandler(async (event, context) => {
return { statusCode: 200, body: JSON.stringify({ ok: true }) };
});
Automatically sets: faas.name, faas.version, faas.invocation_id, faas.coldstart, faas.trigger, cloud.provider, cloud.region, cloud.account.id.
With trace context access (traceLambda):
import { traceLambda } from 'autotel-aws/lambda';
export const handler = traceLambda((ctx) => async (event, lambdaContext) => {
ctx.setAttribute('user.id', event.userId);
const result = await processOrder(event);
ctx.setAttribute('order.status', result.status);
return { statusCode: 200 };
});
LambdaInstrumentationConfig options:
| Option | Default | Description |
|---|---|---|
captureResponse | false | Serialise response into lambda.response attribute (capped at 4 096 bytes) |
extractTraceContext | true | Extract W3C / X-Ray trace context from the incoming event |
service | — | Override service name |
Three approaches — pick one:
A. Instrument an existing client:
import { instrumentSDK } from 'autotel-aws/sdk';
import { S3Client } from '@aws-sdk/client-s3';
const s3 = instrumentSDK(new S3Client({ region: 'us-east-1' }));
// All s3.send() calls are now traced automatically
B. Create a pre-instrumented client:
import { createTracedClient } from 'autotel-aws/sdk';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
const dynamo = createTracedClient(DynamoDBClient, { region: 'us-east-1' });
C. Global auto-instrumentation (call once at startup):
import { autoInstrumentAWS } from 'autotel-aws/sdk';
autoInstrumentAWS();
// All subsequently created clients are instrumented automatically
const s3 = new S3Client({});
Disable with disableAutoInstrumentAWS(). Check status with isAutoInstrumentEnabled().
All service helpers follow the same curried factory pattern:
traceXxx(config)(ctx => async (...args) => { ... })
S3:
import { traceS3 } from 'autotel-aws/s3';
const getFile = traceS3({ operation: 'GetObject', bucket: 'my-bucket' })(
(ctx) => async (key: string) => {
ctx.setAttribute('aws.s3.key', key);
return await s3.send(new GetObjectCommand({ Bucket: 'my-bucket', Key: key }));
}
);
await getFile('path/to/file.txt');
Auto-sets: aws.s3.bucket. Span name: s3.GetObject.
DynamoDB:
import { traceDynamoDB } from 'autotel-aws/dynamodb';
const getUser = traceDynamoDB({ operation: 'GetItem', table: 'users' })(
(ctx) => async (userId: string) => {
ctx.setAttribute('db.statement', 'GetItem WHERE id = :id');
const result = await dynamodb.send(new GetItemCommand({
TableName: 'users',
Key: { id: { S: userId } },
}));
if (result.ConsumedCapacity?.CapacityUnits) {
ctx.setAttribute('aws.dynamodb.consumed_capacity', result.ConsumedCapacity.CapacityUnits);
}
return result.Item;
}
);
Auto-sets: db.system ('dynamodb'), db.operation, db.name, aws.dynamodb.table_names. Span name: dynamodb.GetItem.
SQS / SNS / Kinesis / Step Functions / EventBridge — follow the same traceXxx({ operation, ... }) pattern via their respective subpaths (autotel-aws/sqs, autotel-aws/sns, etc.).
import { configureXRay } from 'autotel-aws/xray';
// Enable X-Ray propagator and ID generator before init()
configureXRay({ propagator: true, idGenerator: true });
await init({ service: 'my-service' });
import { getAWSResourceDetectors } from 'autotel-aws';
const detectors = await getAWSResourceDetectors();
// detectors = [awsEc2Detector, awsEcsDetector, awsEksDetector] if
// @opentelemetry/resource-detector-aws is installed; [] otherwise
// WRONG: SDK clients created before SDK is initialised
import { S3Client } from '@aws-sdk/client-s3';
const s3 = new S3Client({});
await init({ service: 'my-service' }); // too late
// CORRECT: init() first, clients after
await init({ service: 'my-service' });
const s3 = instrumentSDK(new S3Client({}));
// WRONG: factory must return an async function; the function is what gets invoked
export const handler = traceLambda((ctx) => {
ctx.setAttribute('foo', 'bar'); // ctx.setAttribute called eagerly — wrong timing
return { statusCode: 200 }; // returning a value, not a handler function
});
// CORRECT: the factory returns the handler function
export const handler = traceLambda((ctx) => async (event, lambdaContext) => {
ctx.setAttribute('foo', 'bar');
return { statusCode: 200 };
});
Lambda cold start code runs synchronously before the handler. If init() is not awaited, the first invocation may execute before the SDK is ready.
// WRONG (at module level, unawaited)
init({ service: 'my-service' }); // returns a Promise, not awaited
// CORRECT: await at module level using top-level await, or guard the handler
await init({ service: 'my-service' });
export const handler = wrapHandler(async (event) => { ... });
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.
autoInstrumentAWS() patches the SDK globally and persists across test files. Always call disableAutoInstrumentAWS() in test teardown, or prefer instrumentSDK() / createTracedClient() for isolated instrumentation.
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).