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-actionsBot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser27.59 kB--
@sentry/browser - with treeshaking flags26.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 flags75.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/react29.38 kB--
@sentry/react (incl. Tracing)48.61 kB--
@sentry/vue33.03 kB--
@sentry/vue (incl. Tracing)48.3 kB--
@sentry/svelte27.61 kB--
CDN Bundle30 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 - uncompressed89.35 kB--
CDN Bundle (incl. Tracing) - uncompressed146.1 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed94.05 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed150.07 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed218.78 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.3 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed269.26 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed282.95 kB--
@sentry/nextjs (client)51.16 kB--
@sentry/sveltekit (client)46.78 kB--
@sentry/core/server78.42 kB--
@sentry/core/browser64.74 kB--
@sentry/node-core62.72 kB--
@sentry/node125.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/light50.72 kB--
@sentry/node - without tracing74.06 kB--
@sentry/aws-serverless85.5 kB--
@sentry/cloudflare (withSentry) - minified181.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 CursorFix in Web

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

@cursorcursorBot 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 CursorFix 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 CursorFix 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
MemberAuthor

Superseded by a stacked split for easier review:

Same change, split into reviewable layers.

Sign up for freeto 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

@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
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-actionsBot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser27.59 kB--
@sentry/browser - with treeshaking flags26.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 flags75.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/react29.38 kB--
@sentry/react (incl. Tracing)48.61 kB--
@sentry/vue33.03 kB--
@sentry/vue (incl. Tracing)48.3 kB--
@sentry/svelte27.61 kB--
CDN Bundle30 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 - uncompressed89.35 kB--
CDN Bundle (incl. Tracing) - uncompressed146.1 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed94.05 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed150.07 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed218.78 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.3 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed269.26 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed282.95 kB--
@sentry/nextjs (client)51.16 kB--
@sentry/sveltekit (client)46.78 kB--
@sentry/core/server78.42 kB--
@sentry/core/browser64.74 kB--
@sentry/node-core62.72 kB--
@sentry/node125.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/light50.72 kB--
@sentry/node - without tracing74.06 kB--
@sentry/aws-serverless85.5 kB--
@sentry/cloudflare (withSentry) - minified181.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 CursorFix in Web

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

@cursorcursorBot 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 CursorFix 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 CursorFix 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
MemberAuthor

Superseded by a stacked split for easier review:

Same change, split into reviewable layers.

Sign up for freeto 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

@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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-actionsBot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser27.59 kB--
@sentry/browser - with treeshaking flags26.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 flags75.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/react29.38 kB--
@sentry/react (incl. Tracing)48.61 kB--
@sentry/vue33.03 kB--
@sentry/vue (incl. Tracing)48.3 kB--
@sentry/svelte27.61 kB--
CDN Bundle30 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 - uncompressed89.35 kB--
CDN Bundle (incl. Tracing) - uncompressed146.1 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed94.05 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed150.07 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed218.78 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.3 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed269.26 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed282.95 kB--
@sentry/nextjs (client)51.16 kB--
@sentry/sveltekit (client)46.78 kB--
@sentry/core/server78.42 kB--
@sentry/core/browser64.74 kB--
@sentry/node-core62.72 kB--
@sentry/node125.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/light50.72 kB--
@sentry/node - without tracing74.06 kB--
@sentry/aws-serverless85.5 kB--
@sentry/cloudflare (withSentry) - minified181.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 CursorFix in Web

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

@cursorcursorBot 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 CursorFix 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 CursorFix 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
MemberAuthor

Superseded by a stacked split for easier review:

Same change, split into reviewable layers.

Sign up for freeto 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

@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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-actionsBot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser27.59 kB--
@sentry/browser - with treeshaking flags26.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 flags75.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/react29.38 kB--
@sentry/react (incl. Tracing)48.61 kB--
@sentry/vue33.03 kB--
@sentry/vue (incl. Tracing)48.3 kB--
@sentry/svelte27.61 kB--
CDN Bundle30 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 - uncompressed89.35 kB--
CDN Bundle (incl. Tracing) - uncompressed146.1 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed94.05 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed150.07 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed218.78 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.3 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed269.26 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed282.95 kB--
@sentry/nextjs (client)51.16 kB--
@sentry/sveltekit (client)46.78 kB--
@sentry/core/server78.42 kB--
@sentry/core/browser64.74 kB--
@sentry/node-core62.72 kB--
@sentry/node125.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/light50.72 kB--
@sentry/node - without tracing74.06 kB--
@sentry/aws-serverless85.5 kB--
@sentry/cloudflare (withSentry) - minified181.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 CursorFix in Web

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

@cursorcursorBot 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 CursorFix 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 CursorFix 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
MemberAuthor

Superseded by a stacked split for easier review:

Same change, split into reviewable layers.

Sign up for freeto 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

@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
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-actionsBot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser27.59 kB--
@sentry/browser - with treeshaking flags26.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 flags75.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/react29.38 kB--
@sentry/react (incl. Tracing)48.61 kB--
@sentry/vue33.03 kB--
@sentry/vue (incl. Tracing)48.3 kB--
@sentry/svelte27.61 kB--
CDN Bundle30 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 - uncompressed89.35 kB--
CDN Bundle (incl. Tracing) - uncompressed146.1 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed94.05 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed150.07 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed218.78 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.3 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed269.26 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed282.95 kB--
@sentry/nextjs (client)51.16 kB--
@sentry/sveltekit (client)46.78 kB--
@sentry/core/server78.42 kB--
@sentry/core/browser64.74 kB--
@sentry/node-core62.72 kB--
@sentry/node125.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/light50.72 kB--
@sentry/node - without tracing74.06 kB--
@sentry/aws-serverless85.5 kB--
@sentry/cloudflare (withSentry) - minified181.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 CursorFix in Web

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

@cursorcursorBot 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 CursorFix 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 CursorFix 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
MemberAuthor

Superseded by a stacked split for easier review:

Same change, split into reviewable layers.

Sign up for freeto 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

@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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-actionsBot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser27.59 kB--
@sentry/browser - with treeshaking flags26.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 flags75.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/react29.38 kB--
@sentry/react (incl. Tracing)48.61 kB--
@sentry/vue33.03 kB--
@sentry/vue (incl. Tracing)48.3 kB--
@sentry/svelte27.61 kB--
CDN Bundle30 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 - uncompressed89.35 kB--
CDN Bundle (incl. Tracing) - uncompressed146.1 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed94.05 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed150.07 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed218.78 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.3 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed269.26 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed282.95 kB--
@sentry/nextjs (client)51.16 kB--
@sentry/sveltekit (client)46.78 kB--
@sentry/core/server78.42 kB--
@sentry/core/browser64.74 kB--
@sentry/node-core62.72 kB--
@sentry/node125.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/light50.72 kB--
@sentry/node - without tracing74.06 kB--
@sentry/aws-serverless85.5 kB--
@sentry/cloudflare (withSentry) - minified181.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 CursorFix in Web

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

@cursorcursorBot 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 CursorFix 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 CursorFix 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
MemberAuthor

Superseded by a stacked split for easier review:

Same change, split into reviewable layers.

Sign up for freeto 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

@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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-actionsBot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser27.59 kB--
@sentry/browser - with treeshaking flags26.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 flags75.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/react29.38 kB--
@sentry/react (incl. Tracing)48.61 kB--
@sentry/vue33.03 kB--
@sentry/vue (incl. Tracing)48.3 kB--
@sentry/svelte27.61 kB--
CDN Bundle30 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 - uncompressed89.35 kB--
CDN Bundle (incl. Tracing) - uncompressed146.1 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed94.05 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed150.07 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed218.78 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.3 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed269.26 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed282.95 kB--
@sentry/nextjs (client)51.16 kB--
@sentry/sveltekit (client)46.78 kB--
@sentry/core/server78.42 kB--
@sentry/core/browser64.74 kB--
@sentry/node-core62.72 kB--
@sentry/node125.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/light50.72 kB--
@sentry/node - without tracing74.06 kB--
@sentry/aws-serverless85.5 kB--
@sentry/cloudflare (withSentry) - minified181.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 CursorFix in Web

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

@cursorcursorBot 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 CursorFix 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 CursorFix 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
MemberAuthor

Superseded by a stacked split for easier review:

Same change, split into reviewable layers.

Sign up for freeto 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

@andreiborza
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
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-actionsBot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser27.59 kB--
@sentry/browser - with treeshaking flags26.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 flags75.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/react29.38 kB--
@sentry/react (incl. Tracing)48.61 kB--
@sentry/vue33.03 kB--
@sentry/vue (incl. Tracing)48.3 kB--
@sentry/svelte27.61 kB--
CDN Bundle30 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 - uncompressed89.35 kB--
CDN Bundle (incl. Tracing) - uncompressed146.1 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed94.05 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed150.07 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed218.78 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed265.3 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed269.26 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed279 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed282.95 kB--
@sentry/nextjs (client)51.16 kB--
@sentry/sveltekit (client)46.78 kB--
@sentry/core/server78.42 kB--
@sentry/core/browser64.74 kB--
@sentry/node-core62.72 kB--
@sentry/node125.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/light50.72 kB--
@sentry/node - without tracing74.06 kB--
@sentry/aws-serverless85.5 kB--
@sentry/cloudflare (withSentry) - minified181.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 CursorFix in Web

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

@cursorcursorBot 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 CursorFix 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 CursorFix 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
MemberAuthor

Superseded by a stacked split for easier review:

Same change, split into reviewable layers.

Sign up for freeto 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

@andreiborza