Skip to content

feat(server-utils): Migrate @opentelemetry/instrumentation-aws-sdk to orchestrion#22138

Closed
andreiborza wants to merge 2 commits into
developfrom
ab/aws-sdk-orchestrion
Closed

feat(server-utils): Migrate @opentelemetry/instrumentation-aws-sdk to orchestrion#22138
andreiborza wants to merge 2 commits into
developfrom
ab/aws-sdk-orchestrion

Conversation

@andreiborza

Copy link
Copy Markdown
Member

Migrates the aws-sdk (v3) instrumentation from the OpenTelemetry InstrumentationBase patcher (vendored in @sentry/aws-serverless) to an orchestrion diagnostics-channel listener, following the mysql (#20900) and graphql (#21885) precedent.

The channel-based integration subscribes to the orchestrion:<smithy-pkg>:send channels the transform injects into the smithy Client.prototype.send (@smithy/core, @smithy/smithy-client, @aws-sdk/smithy-client), and emits the same spans as the OTel integration for every service (S3, DynamoDB, SQS, SNS, Lambda, Kinesis, SecretsManager, StepFunctions, Bedrock), with a distinct auto.aws.orchestrion.aws-sdk origin.

  • The subscriber and OTel-free service extensions live in @sentry/server-utils and are registered in channelIntegrations, so the integration is reachable via @sentry/node's experimentalUseDiagnosticsChannelInjection().
  • @sentry/aws-serverless (where the OTel Aws integration ships today) swaps in the channel version under the same opt-in, via a small applyDiagnosticsChannelInjectionIntegrations helper extracted from @sentry/node.
  • SQS/SNS/Lambda trace propagation is preserved using Sentry-native sentry-trace/baggage headers instead of OTel propagation.inject.

Testing reuses the existing nock-mocked aws-integration and aws-integration-streamed node-integration-test suites: they already run under the INJECT_ORCHESTRION CI matrix, so the diagnostics-channel path is asserted for identical spans across both smithy stacks (latest + legacy 3.1041.0) and ESM/CJS. Only the expected origin is parametrized.

closes #20946

…to orchestrion

Migrates the aws-sdk (v3) instrumentation from the OTel `InstrumentationBase`
patcher (vendored in `@sentry/aws-serverless`) to an orchestrion
diagnostics-channel listener.

The channel-based integration subscribes to `orchestrion:<smithy-pkg>:send`
(injected into the smithy `Client.prototype.send`) and emits the same spans as
the OTel integration for all services (S3, DynamoDB, SQS, SNS, Lambda, Kinesis,
SecretsManager, StepFunctions, Bedrock) with a distinct
`auto.aws.orchestrion.aws-sdk` origin.

Registered in `channelIntegrations` so it is reachable via `@sentry/node`'s
`experimentalUseDiagnosticsChannelInjection()`, and swapped in for the OTel
`Aws` integration in `@sentry/aws-serverless` under the same opt-in.

closes #20946

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 27.59 kB - -
@sentry/browser - with treeshaking flags 26.03 kB - -
@sentry/browser (incl. Tracing) 46.34 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 48.13 kB - -
@sentry/browser (incl. Tracing, Profiling) 51.12 kB - -
@sentry/browser (incl. Tracing, Replay) 85.62 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 75.26 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 90.32 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 102.97 kB - -
@sentry/browser (incl. Feedback) 44.76 kB - -
@sentry/browser (incl. sendFeedback) 32.38 kB - -
@sentry/browser (incl. FeedbackAsync) 37.51 kB - -
@sentry/browser (incl. Metrics) 28.67 kB - -
@sentry/browser (incl. Logs) 28.91 kB - -
@sentry/browser (incl. Metrics & Logs) 29.59 kB - -
@sentry/react 29.38 kB - -
@sentry/react (incl. Tracing) 48.61 kB - -
@sentry/vue 33.03 kB - -
@sentry/vue (incl. Tracing) 48.3 kB - -
@sentry/svelte 27.61 kB - -
CDN Bundle 30 kB - -
CDN Bundle (incl. Tracing) 48.32 kB - -
CDN Bundle (incl. Logs, Metrics) 31.57 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.64 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 70.81 kB - -
CDN Bundle (incl. Tracing, Replay) 85.84 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 87.14 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 91.64 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.92 kB - -
CDN Bundle - uncompressed 89.35 kB - -
CDN Bundle (incl. Tracing) - uncompressed 146.1 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 94.05 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 150.07 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 218.78 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 265.3 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 269.26 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 279 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 282.95 kB - -
@sentry/nextjs (client) 51.16 kB - -
@sentry/sveltekit (client) 46.78 kB - -
@sentry/core/server 78.42 kB - -
@sentry/core/browser 64.74 kB - -
@sentry/node-core 62.72 kB - -
@sentry/node 125.37 kB -0.01% -1 B 🔽
⛔️ @sentry/node (incl. diagnostics channel injection) (max: 142 kB) 143.16 kB +3.34% +4.62 kB 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 69.95 kB - -
@sentry/node/light 50.72 kB - -
@sentry/node - without tracing 74.06 kB - -
@sentry/aws-serverless 85.5 kB - -
@sentry/cloudflare (withSentry) - minified 181.71 kB - -
@sentry/cloudflare (withSentry) 449.16 kB - -

View base workflow run


// Streaming responses end the span when their wrapped stream is consumed (see
// bedrock-runtime); the helper must not end it on `send` settling. Errors always end here.
return !!requestMetadata?.isStream && !failed;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stream spans leak on hook failure

Medium Severity

For Bedrock streaming commands, deferSpanEnd always skips ending the span when isStream is set and the request did not fail, even if the wrapped responseHook threw inside safe. The AWS call still succeeds, but no wrapper runs to call span.end(), leaving a non-finishing client span.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 86e221a. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 3 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 46c35c3. Configure here.


if (request.commandInput?.body) {
const requestBody = JSON.parse(request.commandInput.body);
if (modelId.includes('amazon.titan')) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unchecked modelId before includes

Low Severity

In InvokeModel pre-span handling, when commandInput.body is present the code calls modelId.includes(...) without ensuring modelId is defined. A body-only invoke can throw inside the orchestrion safe() wrapper, so instrumentation skips span creation while the AWS call still runs.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 46c35c3. Configure here.


if (Object.keys(attributes).length + headerKeys.length <= MAX_MESSAGE_ATTRIBUTES) {
for (const key of headerKeys) {
(attributes as AwsSdkContextObject)[key] = { DataType: 'String', StringValue: headers[key] } as any;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as any lacks explanation comment

Low Severity

New SDK code assigns SQS/SNS message attribute entries with an as any cast and no comment explaining why a narrower type is not used, which violates the project’s PR review rules for any in production SDK source.

Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 46c35c3. Configure here.

@andreiborza

Copy link
Copy Markdown
Member Author

Superseded by a stacked split for easier review:

Same change, split into reviewable layers.

@andreiborza andreiborza closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rewrite @opentelemetry/instrumentation-aws-sdk to orchestrion

1 participant