Skip to content

fix(cloudflare): Filter CREATE INDEX spans on cf_-prefixed tables - #22650

Merged
JPeer264 merged 2 commits into
jp/filter-optional-sql-spansfrom
jp/filter-cloudflare-sql-spans
Jul 27, 2026
Merged

fix(cloudflare): Filter CREATE INDEX spans on cf_-prefixed tables#22650
JPeer264 merged 2 commits into
jp/filter-optional-sql-spansfrom
jp/filter-cloudflare-sql-spans

Conversation

@JPeer264

Copy link
Copy Markdown
Member

In the agent SDK there were still couple of SQL statements injected as spans which didn't give any value. With that PR they are now filtered out (like this one)

getSqlQuerySummary follows the upstream OTel convention of summarizing CREATE INDEX idx ON t (...) as CREATE INDEX idx - the indexed table never appears in the summary, so targetsCloudflareInternalTable could not see that framework statements like create index idx_stream_chunks_stream_id on cf_ai_chat_stream_chunks(...) target internal tables. They leaked through as unfiltered db.query spans on every Durable Object boot.

The filter now also receives the sanitized query text and, for CREATE [UNIQUE] INDEX statements, checks the ON-clause target against the cf_ prefix and the durableObjectSqlSpanAllowlist option. The summary itself (and therefore span names) stays OTel-conformant. The tests were switched to run the same sanitize -> summarize -> filter pipeline as the instrumentation.

`getSqlQuerySummary` follows the upstream OTel convention of summarizing
`CREATE INDEX idx ON t (...)` as `CREATE INDEX idx` — the indexed table never
appears in the summary, so `targetsCloudflareInternalTable` could not see
that framework statements like `create index idx_stream_chunks_stream_id on
cf_ai_chat_stream_chunks(...)` target internal tables. They leaked through as
unfiltered `db.query` spans on every Durable Object boot.

The filter now also receives the sanitized query text and, for
`CREATE [UNIQUE] INDEX` statements, checks the ON-clause target against the
`cf_` prefix and the `durableObjectSqlSpanAllowlist` option. The summary
itself (and therefore span names) stays OTel-conformant. The tests were
switched to run the same sanitize -> summarize -> filter pipeline as the
instrumentation.

Co-Authored-By: Claude <noreply@anthropic.com>
@JPeer264 JPeer264 self-assigned this Jul 27, 2026
@JPeer264
JPeer264 requested a review from a team as a code owner July 27, 2026 07:13
@JPeer264
JPeer264 requested review from andreiborza and isaacs and removed request for a team July 27, 2026 07:13
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 27.95 kB -0.25% -70 B 🔽
@sentry/browser - with treeshaking flags 26.39 kB -0.26% -68 B 🔽
@sentry/browser (incl. Tracing) 46.41 kB -0.28% -127 B 🔽
@sentry/browser (incl. Tracing + Span Streaming) 48.18 kB +1.52% +720 B 🔺
@sentry/browser (incl. Tracing, Profiling) 51.21 kB -0.18% -88 B 🔽
@sentry/browser (incl. Tracing, Replay) 85.69 kB -0.21% -178 B 🔽
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 75.33 kB -0.25% -182 B 🔽
@sentry/browser (incl. Tracing, Replay with Canvas) 90.4 kB -0.2% -175 B 🔽
@sentry/browser (incl. Tracing, Replay, Feedback) 103.06 kB -0.16% -163 B 🔽
@sentry/browser (incl. Feedback) 45.13 kB -0.16% -71 B 🔽
@sentry/browser (incl. sendFeedback) 32.74 kB -0.24% -78 B 🔽
@sentry/browser (incl. FeedbackAsync) 37.8 kB -0.16% -58 B 🔽
@sentry/browser (incl. Metrics) 29.04 kB -0.27% -77 B 🔽
@sentry/browser (incl. Logs) 29.26 kB -0.25% -73 B 🔽
@sentry/browser (incl. Metrics & Logs) 29.97 kB -0.25% -75 B 🔽
@sentry/react 29.75 kB -0.16% -46 B 🔽
@sentry/react (incl. Tracing) 48.71 kB -0.29% -138 B 🔽
@sentry/vue 33.38 kB -1.74% -590 B 🔽
@sentry/vue (incl. Tracing) 48.4 kB -0.29% -140 B 🔽
@sentry/svelte 27.97 kB -0.26% -71 B 🔽
CDN Bundle 30.28 kB -0.13% -38 B 🔽
CDN Bundle (incl. Tracing) 48.26 kB +1.15% +547 B 🔺
CDN Bundle (incl. Logs, Metrics) 31.85 kB -0.16% -50 B 🔽
CDN Bundle (incl. Tracing, Logs, Metrics) 49.58 kB +1.01% +492 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 71.13 kB -0.07% -48 B 🔽
CDN Bundle (incl. Tracing, Replay) 85.83 kB +0.61% +517 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 87.14 kB +0.62% +535 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 91.6 kB +0.54% +487 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.89 kB +0.54% +495 B 🔺
CDN Bundle - uncompressed 90.15 kB -0.13% -113 B 🔽
CDN Bundle (incl. Tracing) - uncompressed 145.22 kB +1.4% +2 kB 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 94.86 kB -0.12% -113 B 🔽
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 149.2 kB +1.37% +2 kB 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 219.62 kB -0.06% -113 B 🔽
CDN Bundle (incl. Tracing, Replay) - uncompressed 264.46 kB +0.76% +1.98 kB 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 268.42 kB +0.75% +1.98 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 278.16 kB +0.72% +1.98 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 282.11 kB +0.71% +1.98 kB 🔺
@sentry/nextjs (client) 51.24 kB -0.32% -164 B 🔽
@sentry/sveltekit (client) 46.84 kB -0.36% -168 B 🔽
@sentry/core/server 80.1 kB +0.66% +524 B 🔺
@sentry/core/browser 52.01 kB +0.92% +470 B 🔺
@sentry/node 123.14 kB +9.48% +10.66 kB 🔺
@sentry/node (incl. diagnostics channel injection) 167.14 kB +6.71% +10.5 kB 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 166 B - -
@sentry/node - without tracing 73.31 kB +18.22% +11.3 kB 🔺
@sentry/aws-serverless 82.82 kB +14.56% +10.52 kB 🔺
@sentry/cloudflare (withSentry) - minified 197.41 kB +0.75% +1.47 kB 🔺
@sentry/cloudflare (withSentry) 485.37 kB +0.6% +2.86 kB 🔺

View base workflow run

Comment on lines +5 to +10
// Runs the same sanitize -> summarize -> filter pipeline as `instrumentSqlStorage`, so the tests
// exercise the real detection path rather than hand-written summaries.
const check = (query: string, allowlist?: Array<string | RegExp>): boolean => {
const sanitized = _INTERNAL_sanitizeSqlQuery(query);
return targetsCloudflareInternalTable(_INTERNAL_getSqlQuerySummary(sanitized), allowlist, sanitized);
};

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.

l: Not a fan of this, if implementation changes and we add extra steps to the actual code path we won't catch regressions heree.

Is there no way reproduce the actual path without having to code one up separately here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yeah you're right. I actually also moved the majority of the calls to instrumentSqlStorage where it made most sense

@JPeer264
JPeer264 merged commit 22a9d22 into develop Jul 27, 2026
279 checks passed
@JPeer264
JPeer264 deleted the jp/filter-cloudflare-sql-spans branch July 27, 2026 15:56
JPeer264 added a commit that referenced this pull request Jul 28, 2026
JPeer264 added a commit that referenced this pull request Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants