fix(platform): Move instrumentation.ts to repo root so prod builds load it#18771
Merged
sergical merged 1 commit intoJul 20, 2026
Merged
Conversation
…ad it Next.js production builds discover middleware.ts and instrumentation.ts by scanning only rootDir = parent of the pages/ (or app/) directory, with no src/ fallback. When pages/ moved from src/pages to the repo root (da6c9f8, Mar 5), rootDir flipped from src/ to the repo root. middleware.ts broke visibly and was moved to the root in that commit, but src/instrumentation.ts was left behind and silently stopped being bundled: hasInstrumentationHook=false, no instrumentation.js or edge-instrumentation.js entries, so register() and Sentry.init never run in the node or edge runtime in production. Since then both docs and develop-docs have emitted zero server-side telemetry: no middleware spans, no http.server spans, no docs.trace.sampled metrics, and no traffic classification. Dev was unaffected because the dev bundler does check src/, which hid the breakage locally. Move instrumentation.ts to the repo root (next to middleware.ts) and import tracesSampler via the sentry-docs path alias. Verified with a local next build: .next/server/ gains instrumentation.js and edge-instrumentation.js, and the edge bundle contains the DSN, tracesSampler, and the docs.trace.sampled metric emission. instrumentation-client.ts stays in src/ because Next resolves it through a webpack alias that checks src/ first. Co-Authored-By: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
sergical
marked this pull request as ready for review
July 20, 2026 20:56
6 tasks
sergical
added a commit
that referenced
this pull request
Jul 22, 2026
…e sampling (#18775) ## DESCRIBE YOUR PR Follow-up to #18771. That PR restored server-side Sentry, which exposed a structural problem: **middleware root spans can never be classified at sampling time.** The root span for a middleware request is Next.js's own `Middleware.execute` OTEL span, created in a detached sandbox *before* any request data reaches Sentry — so `tracesSampler` fires with no headers and no user-agent. Result since the fix landed: ~100% of middleware spans classify as `unknown` and get sampled at 30% — including bots — ingesting ~264k/day spans that carry no information (the span name is collapsed to `middleware GET`, no URL). Rather than fighting this with send-time filtering wrappers, this PR moves each signal to where the data actually lives: - **`middleware.ts` counts every request.** It already classifies each request to stamp `x-traffic-type`; now it classifies once and emits a `docs.request.classified` counter (`traffic_type`, `device_type`, plus the matched `agent` for AI traffic) for every request — no sampling, 100% accurate, and redirect requests are now counted too (previously they were skipped). This metric is the system of record for agent/bot/user traffic on the docs. - **`tracesSampler` drops middleware root spans (rate 0) and becomes a pure sampling function.** The proven classification for downstream node routes is unchanged: `x-traffic-type` header first, user-agent fallback — agents 100%, bots 0%, users 30%. All metric emission is removed from the sampler. - **Removes the temporary `beforeSendTransaction` hook** in `instrumentation.ts` that renamed middleware transactions — dead code once middleware spans stop flowing. Net effect on ingestion: middleware span volume drops from ~264k/day to zero (they carried no insight), metric volume stays roughly the same as the old `docs.trace.sampled` emission, and per-request edge CPU goes down (one classification instead of two, sampler exits immediately for middleware spans). **Dashboard note:** `docs.trace.sampled` stops being emitted. Queries should move to `docs.request.classified`, which counts requests rather than sampling decisions — a clean epoch, since 4.5 months of the old metric are all-`unknown` zombie data anyway. **Post-deploy verification** (`sentry/docs`, then `sentry/develop-docs`): - `metrics · docs.request.classified · group by traffic_type` → real `ai_agent` / `bot` / `user` split; `group by agent` → which AI agents consume the docs - `spans · span.op:http.server.middleware · release:<new sha>` → should drop to zero - `spans · span.op:http.server release:<new sha> · group by ...` → node route spans keep flowing with header-based classification ## IS YOUR CHANGE URGENT? Help us prioritize incoming PRs by letting us know when the change needs to go live. - [ ] Urgent deadline (GA date, etc.): <!-- ENTER DATE HERE --> - [ ] Other deadline: <!-- ENTER DATE HERE --> - [x] None: Not urgent, can wait up to 1 week+ ## SLA - Teamwork makes the dream work, so please add a reviewer to your PRs. - Please give the docs team up to 1 week to review your PR unless you've added an urgent due date to it. Thanks in advance for your help! ## PRE-MERGE CHECKLIST *Make sure you've checked the following before merging your changes:* - [ ] Checked Vercel preview for correctness, including links - [ ] PR was reviewed and approved by any necessary SMEs (subject matter experts) - [ ] PR was reviewed and approved by a member of the [Sentry docs team](https://github.com/orgs/getsentry/teams/docs) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
DESCRIBE YOUR PR
Production builds of both docs.sentry.io and develop.sentry.dev have emitted zero server-side Sentry telemetry since Mar 5, 2026 — no middleware spans, no
http.serverspans, nodocs.trace.sampledmetrics, and no AI-agent/bot/user traffic classification. This one-file move fixes it.Root cause: Next.js production builds discover
middleware.tsandinstrumentation.tsby scanning onlyrootDir— the parent of thepages/(orapp/) directory — with nosrc/fallback (next/dist/build/index.js, identical logic in 15.1 and 15.5). For two years the repo hadsrc/pages, sorootDirwassrc/and bothsrc/middleware.tsandsrc/instrumentation.tswere found. When #16687 movedpages/to the repo root,rootDirflipped to the repo root: middleware broke visibly (redirects died) and was moved to the root in that same PR, butsrc/instrumentation.tswas left behind and silently dropped from the build —register()andSentry.initstopped running in the node and edge runtimes entirely. Dev was unaffected because the dev bundler does checksrc/, which hid the breakage locally.This also explains why the SDK bump in #18723 changed nothing in production: the sampler it fixed never executes, because the file that installs it is not in the build.
instrumentation.tsfromsrc/to the repo root (next tomiddleware.ts), importingtracesSamplervia thesentry-docspath aliasinstrumentation-client.tsintentionally stays insrc/— Next resolves it through a webpack alias that checkssrc/first, which is why browser telemetry never brokeVerified with a local
next build: before the move,.next/server/contains no instrumentation entries; after it,instrumentation.jsandedge-instrumentation.jsare emitted and the edge bundle contains the DSN,tracesSampler, and thedocs.trace.sampledmetric emission.Post-deploy verification (in
sentry/docsandsentry/develop-docs):spans · span.op:http.server.middleware · group by sdk.version, release→ should show the current release on SDK 10.65metrics · docs.trace.sampled · group by traffic_type→ should split intoai_agent/bot/userinstead of being absentIS YOUR CHANGE URGENT?
Help us prioritize incoming PRs by letting us know when the change needs to go live.
SLA
Thanks in advance for your help!
PRE-MERGE CHECKLIST
Make sure you've checked the following before merging your changes:
🤖 Generated with Claude Code