Skip to content

Add TracingChannel support for APM instrumentation#1

Open
sergical wants to merge 8 commits into
mainfrom
feat/tracing-channel
Open

Add TracingChannel support for APM instrumentation#1
sergical wants to merge 8 commits into
mainfrom
feat/tracing-channel

Conversation

@sergical

@sergical sergical commented May 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds native diagnostics_channel TracingChannel instrumentation to Remix 3's three subsystems
  • remix:request — traces middleware and route handler execution in fetch-router
  • remix:render — traces server-side rendering in ui/server
  • remix:asset — traces on-demand script/style compilation in assets
  • Zero cost when no subscribers are registered (hasSubscribers gating)
  • Includes a demo app (demos/tracing-channels) that subscribes to all three channels and logs spans with timing

This enables APM tools (Sentry, OpenTelemetry, Datadog, etc.) to subscribe to structured lifecycle events without monkey-patching. Since Remix 3 is a closure-based, ESM-only framework, monkey-patching would be especially fragile — TracingChannel provides a stable, first-party surface from day one.

Traced request flow

remix:request (type: handler) — GET /
  remix:render               — renderToStream
    remix:request (type: handler) — GET / (frame sub-request)

remix:request (type: handler) — GET /assets/*path
  remix:asset                — script compilation

Demo output

✓ TracingChannel subscribers active (remix:request, remix:render, remix:asset)
→ handler GET /
  → render http://localhost:44200/
  ← handler GET / 1.86ms
← render http://localhost:44200/ 3.91ms

Test plan

  • All 77 existing fetch-router tests pass
  • All three packages type-check clean (tsc --noEmit)
  • Demo app starts, serves requests, and logs tracing spans
  • No changes to existing behavior when no subscribers are registered
  • Verify with a real Sentry SDK subscriber (next step: @sentry/remix)

🤖 Generated with Claude Code

sergical and others added 8 commits May 4, 2026 14:05
Adds native diagnostics_channel TracingChannel instrumentation to three
subsystems so APM tools can subscribe to structured lifecycle events
without monkey-patching:

- remix:request — traces middleware and route handler execution in fetch-router
- remix:render — traces server-side rendering in ui/server
- remix:asset — traces on-demand script/style compilation in assets

Zero cost when no subscribers are registered (hasSubscribers gating).
Includes a demo app (demos/tracing-channels) that logs all three channels.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces console logging with real Sentry OTel spans via
otel-tracing-channel. All three channels (remix:request,
remix:render, remix:asset) now export spans with correct
parent-child nesting to a Sentry DSN.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Injects sentry-trace and baggage meta tags into the HTML response.
Client-side JS reads these and sends them on fetch requests, linking
browser-initiated requests to the server-side trace.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Browser SDK reads sentry-trace meta tag from server-rendered HTML,
continues the server trace, and automatically attaches trace headers
to fetch() calls — connecting browser and server spans in one trace.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Guard against calling span.end() twice when TracingChannel fires
  both error and asyncEnd on promise rejection
- Mark @sentry/browser as external for the asset server (pnpm store
  paths fall outside the allow glob)
- Simplify client entry to manual header propagation (no browser SDK
  bundling needed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use the CDN bundle (v10.51.0) instead of bundling @sentry/browser
through the asset server. browserTracingIntegration() reads the
sentry-trace meta tag and propagates headers on all fetch() calls,
connecting browser pageload + API requests to the server trace.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Handler name is already 'GET /' from the framework, don't prepend
  the method again
- Use op 'remix.handler' instead of 'http.server' to avoid looking
  like a duplicate of Sentry's built-in HTTP span

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant