Skip to content

Apply outputFileTracingIncludes to the instrumentation entry#92616

Draft
yogeshwaran-c wants to merge 1 commit intovercel:canaryfrom
yogeshwaran-c:fix/instrumentation-standalone-trace
Draft

Apply outputFileTracingIncludes to the instrumentation entry#92616
yogeshwaran-c wants to merge 1 commit intovercel:canaryfrom
yogeshwaran-c:fix/instrumentation-standalone-trace

Conversation

@yogeshwaran-c
Copy link
Copy Markdown

What?

Make outputFileTracingIncludes: { '/instrumentation': [...] } actually take effect for the instrumentation hook entry. Today the include globs are silently dropped, so extra files (native .node prebuilds, support assets, etc.) pulled in via instrumentation.ts go missing from .next/server/instrumentation.js.nft.json and from the standalone output, even when the user has configured them.

Why?

The post-trace include/exclude pass in collect-build-traces.ts derives a route key from the webpack entry name. For app/* and pages/* entries it normalizes to a leading-slash route (/foo), and the user's outputFileTracingIncludes glob keys are matched against that. But the instrumentation hook is registered as a top-level webpack entry whose name is the bare string instrumentation — no app/ or pages/ prefix — so neither branch ran, route stayed as 'instrumentation', and a key like '/instrumentation' (which is what users naturally write to match the convention) never matched.

The result is exactly the user's report in #68740: an instrumentation package such as @splunk/otel ships a native .node binary that nft can't statically resolve, and there's no working knob to add it back. outputFileTracingIncludes looks like the right tool but is a no-op for this entry.

How?

Treat entryName === 'instrumentation' as a special case in the post-trace pass and normalize its route to /instrumentation, mirroring how app/* and pages/* entries are normalized. After this, outputFileTracingIncludes: { '/instrumentation': ['./node_modules/@splunk/otel/prebuilds/**/*'] } works the same way '/app/route1': [...] does for an app router route, and the matching files land in instrumentation.js.nft.json and the standalone output.

The change is intentionally minimal — one new branch in one function — and does not touch the trace generation, the standalone copy step, or the existing app//pages/ paths.

Scope / known limitation

This post-trace pass is webpack-only. Turbopack does not populate chunksTrace.entryNameFilesMap, so the entire outputFileTracingIncludes/outputFileTracingExcludes post-pass is already a no-op under Turbopack today (the existing build-trace-extra-entries integration test is describe.skip'd for Turbopack for the same reason). The fix here brings instrumentation to feature parity with how app/* and pages/* entries already behave under webpack. Turbopack parity for outputFileTracingIncludes is a larger, separate piece of work and is not in scope.

Test plan

Added test/integration/build-trace-extra-entries-instrumentation/:

  • Fixture: app router project with instrumentation.js, an include-me/native-binary.node stub, and next.config.js setting outputFileTracingIncludes: { '/instrumentation': ['./include-me/**/*'] }.
  • Test: runs nextBuild and asserts that include-me/native-binary.node is present in .next/server/instrumentation.js.nft.json.
  • Gated on IS_TURBOPACK_TEST, matching the existing build-trace-extra-entries suite.

Verified locally on Windows / webpack:

  • New test fails on canary (Expected: true / Received: false) and passes after the fix.
  • Pre-existing build-trace-extra-entries test was checked and is unaffected by this change (it fails identically on canary and on this branch — unrelated to the fix; it asserts app/route1 includes that aren't landing on this Windows env).

Fixes #68740

The instrumentation hook is registered as a webpack entry whose name is
the bare string `instrumentation` (no `app/` or `pages/` prefix). The
post-trace include/exclude pass in `collect-build-traces.ts` only
normalized `app/*` and `pages/*` entries into a leading-slash route key,
so a user-supplied `outputFileTracingIncludes: { '/instrumentation': [...] }`
silently never matched the instrumentation entry. The result was that
extra files (e.g. native `.node` binaries pulled in by an OpenTelemetry
or similar instrumentation package) were missing from
`.next/server/instrumentation.js.nft.json` and therefore from the
standalone output, even though the user had configured them.

Treat `entryName === 'instrumentation'` as a special case and normalize
its route to `/instrumentation`, so the same `/`-prefixed convention
users already use for app and pages routes works for instrumentation
too.

The behavior is webpack-only today; Turbopack does not populate
`entryNameFilesMap` and therefore skips this post-trace pass entirely.
The new test is gated on `IS_TURBOPACK_TEST`, mirroring the existing
`build-trace-extra-entries` suite.

Fixes vercel#68740
@nextjs-bot
Copy link
Copy Markdown
Collaborator

Allow CI Workflow Run

  • approve CI run for commit: b854d8c

Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Instrumentation files not included in standalone output

2 participants