Skip to content

feat(cloudflare): Add R2 bucket auto-instrumentation - #21327

Merged
JPeer264 merged 3 commits into
developfrom
jp/cloudflare-r2-instrumentation
Jun 20, 2026
Merged

feat(cloudflare): Add R2 bucket auto-instrumentation#21327
JPeer264 merged 3 commits into
developfrom
jp/cloudflare-r2-instrumentation

Conversation

@JPeer264

@JPeer264JPeer264 commented Jun 3, 2026

Copy link
Copy Markdown
Member

closes#20836
closes JS-2448

This implements R2 spans. All attributes were taken from Cloudflare itself. The only thing which does not exist in Cloudflare and is added here (inspired by AWS S3), is cloudflare.r2.bucket and gives information of the binding itself.

This should be merged after the Sentry conventions PR and the Sentry docs PR (or at least after approval, in case some OPs change)


AI generated text:

Auto-detect R2 bucket bindings via duck-typing in instrumentEnv and wrap all operations with spans. Span names and attributes align with Cloudflare's built-in tracing conventions (r2_get, r2_put, etc.).

Instrumented methods: get, head, put, delete, list, createMultipartUpload, resumeMultipartUpload, and the resulting multipart upload operations (uploadPart, abort, complete).

@JPeer264JPeer264 self-assigned this Jun 3, 2026
@JPeer264
JPeer264 requested a review from a team as a code ownerJune 3, 2026 13:21
@JPeer264
JPeer264 requested review from andreiborza and mydea and removed request for a teamJune 3, 2026 13:21
Comment on lines +75 to +82
export function isR2Bucket(item: unknown): item is R2Bucket {
return (
item != null &&
isNotJSRPC(item) &&
typeof item.head === 'function' &&
typeof item.put === 'function' &&
typeof item.createMultipartUpload === 'function'
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bug: The isR2Bucket function uses fragile duck-typing to detect R2 buckets, which could misidentify other objects and lacks test coverage for validation.
Severity: LOW

Suggested Fix

Add comprehensive unit tests for the isR2Bucket function in isBinding.test.ts. The tests should cover positive and negative cases, including objects that have some but not all of the required methods, to ensure the detection logic is robust and prevent future regressions.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/cloudflare/src/utils/isBinding.ts#L75-L82
Potential issue: The `isR2Bucket` function identifies R2 buckets by checking for the
presence of `head`, `put`, and `createMultipartUpload` methods. This duck-typing
approach is inherently fragile and could lead to false positives. If a different type of
object, such as a custom user object or a future Cloudflare binding, happens to have the
same method names, it would be incorrectly wrapped for R2 instrumentation. This would
not cause a crash but would generate incorrect telemetry spans, which could mislead
debugging efforts. The analysis highlights that this new function lacks any test
coverage in `isBinding.test.ts`, unlike other binding detection functions in the same
file.

Also affects:

  • packages/cloudflare/src/instrumentations/worker/instrumentEnv.ts:57~62

Did we get this right? 👍 / 👎 to inform future reviews.

@linear-code

Copy link
Copy Markdown

JS-2448

@JPeer264
JPeer264 requested review from isaacs and removed request for mydeaJune 3, 2026 13:32
@github-actions

github-actionsBot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser27.45 kB--
@sentry/browser - with treeshaking flags25.88 kB--
@sentry/browser (incl. Tracing)45.94 kB--
@sentry/browser (incl. Tracing + Span Streaming)47.7 kB--
@sentry/browser (incl. Tracing, Profiling)50.73 kB--
@sentry/browser (incl. Tracing, Replay)85.14 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags74.73 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)89.83 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)102.49 kB--
@sentry/browser (incl. Feedback)44.62 kB--
@sentry/browser (incl. sendFeedback)32.24 kB--
@sentry/browser (incl. FeedbackAsync)37.38 kB--
@sentry/browser (incl. Metrics)28.52 kB--
@sentry/browser (incl. Logs)28.76 kB--
@sentry/browser (incl. Metrics & Logs)29.45 kB--
@sentry/react29.25 kB--
@sentry/react (incl. Tracing)48.24 kB--
@sentry/vue32.61 kB--
@sentry/vue (incl. Tracing)47.8 kB--
@sentry/svelte27.48 kB--
CDN Bundle29.84 kB--
CDN Bundle (incl. Tracing)47.85 kB--
CDN Bundle (incl. Logs, Metrics)31.39 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)49.19 kB--
CDN Bundle (incl. Replay, Logs, Metrics)70.7 kB--
CDN Bundle (incl. Tracing, Replay)85.21 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)86.48 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)91.05 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)92.31 kB--
CDN Bundle - uncompressed88.8 kB--
CDN Bundle (incl. Tracing) - uncompressed144.84 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed93.5 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed148.81 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed218.33 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed263.7 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed267.66 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed277.4 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed281.35 kB--
@sentry/nextjs (client)50.63 kB--
@sentry/sveltekit (client)46.33 kB--
@sentry/core/server75.85 kB--
@sentry/core/browser63.01 kB--
@sentry/node-core61.63 kB-0.01%-1 B 🔽
@sentry/node123.61 kB--
@sentry/node/import (ESM hook with diagnostics-channel injection)69.95 kB--
@sentry/node/light50.55 kB--
@sentry/node - without tracing73.69 kB--
@sentry/aws-serverless84.89 kB-0.01%-1 B 🔽
@sentry/cloudflare (withSentry) - minified175.71 kB+1.63%+2.81 kB 🔺
@sentry/cloudflare (withSentry)437.84 kB+1.25%+5.36 kB 🔺

View base workflow run

@JPeer264
JPeer264force-pushed the jp/cloudflare-r2-instrumentation branch from 3605367 to 3671f29CompareJune 3, 2026 13:54
@github-actions

Copy link
Copy Markdown
Contributor

👋 @isaacs, @andreiborza — Please review this PR when you get a chance!

Comment threadpackages/cloudflare/src/instrumentations/worker/instrumentR2.ts Outdated
const requestKey = Array.isArray(key) ? key.join(', ') : typeof key === 'string' ? key : undefined;

return {
op: 'cloud.r2',

@andreiborzaandreiborzaJun 9, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

m: This op seems weird, maybe file would make a more meaningful op to mark that these are operations on the "filesystem" (I know it's not 100% applicable as these are objects but seems the closest).

@JPeer264JPeer264Jun 15, 2026

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Maybe cloudflare.r2 fits the best, as it is definitely no file

Edit: I asked internally what we could use the best.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Now it changed to a proper OP 💯

...(requestKey !== undefined && { 'cloudflare.r2.request.key': requestKey }),
...(isR2ListOptions(key) && key.prefix !== undefined && { 'cloudflare.r2.request.prefix': key.prefix }),
...(isR2ListOptions(key) && key.delimiter !== undefined && { 'cloudflare.r2.request.delimiter': key.delimiter }),
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'cloud.r2',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

and here.

@github-actions

Copy link
Copy Markdown
Contributor

👋 @isaacs — Please review this PR when you get a chance!

@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 1 potential issue.

Fix All in Cursor

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

Reviewed by Cursor Bugbot for commit de254da. Configure here.

@JPeer264
JPeer264force-pushed the jp/cloudflare-r2-instrumentation branch from de254da to e51fed0CompareJune 15, 2026 09:05
@JPeer264
JPeer264 marked this pull request as draft June 16, 2026 11:24
@JPeer264

JPeer264 commented Jun 16, 2026

Copy link
Copy Markdown
MemberAuthor

Moving to draft as the OP is not yet decided for object (see getsentry/sentry-docs#18410)

Also the e2e tests are failing

@JPeer264
JPeer264force-pushed the jp/cloudflare-r2-instrumentation branch 2 times, most recently from 03f9066 to 2be24fbCompareJune 16, 2026 15:22
@JPeer264
JPeer264 marked this pull request as ready for review June 16, 2026 15:22

@andreiborzaandreiborza left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice

@JPeer264
JPeer264force-pushed the jp/cloudflare-r2-instrumentation branch from f5359b8 to 97398f7CompareJune 17, 2026 17:16
@JPeer264
JPeer264 enabled auto-merge (squash) June 17, 2026 17:16
@JPeer264
JPeer264force-pushed the jp/cloudflare-r2-instrumentation branch from 97398f7 to 2d8e107CompareJune 19, 2026 06:29
JPeer264and others added 3 commits June 20, 2026 11:46
Auto-detect R2 bucket bindings via duck-typing in instrumentEnv and
wrap all operations with spans. Span names and attributes align with
Cloudflare's built-in tracing conventions (r2_get, r2_put, etc.).
Instrumented methods: get, head, put, delete, list,
createMultipartUpload, resumeMultipartUpload, and the resulting
multipart upload operations (uploadPart, abort, complete).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@JPeer264
JPeer264force-pushed the jp/cloudflare-r2-instrumentation branch from 2d8e107 to 456a806CompareJune 20, 2026 09:47
@JPeer264
JPeer264 merged commit 1024839 into developJun 20, 2026
283 checks passed
@JPeer264
JPeer264 deleted the jp/cloudflare-r2-instrumentation branch June 20, 2026 10:07
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.

Cloudflare R2 instrumentation

2 participants

@JPeer264@andreiborza