Skip to content

feat(core, node): portable Express integration#19928

Draft
isaacs wants to merge 3 commits intodevelopfrom
isaacschlueter/portable-express-integration
Draft

feat(core, node): portable Express integration#19928
isaacs wants to merge 3 commits intodevelopfrom
isaacschlueter/portable-express-integration

Conversation

@isaacs
Copy link
Member

@isaacs isaacs commented Mar 21, 2026

This extracts the functionality from the OTel Express intstrumentation,
replacing it with a portable standalone integration in @sentry/core,
which can be extended and applied to patch any Express module import in
whatever way makes sense for the platform in question.

Currently in node, that is still an OpenTelemetry intstrumentation, but
just handling the automatic module load instrumentation, not the entire
tracing integration.

This is somewhat a proof of concept, to see what it takes to port a
fairly invovled OTel integration into a state where it can support all
of the platforms that we care about, but it does impose a bit less of a
translation layer between OTel and Sentry semantics (for example, no
need to use the no-op span.recordException()).

The only user-visible change (beyond the additional export in
@sentry/core, of course) is that spans have an origin of
auto.http.express rather than auto.http.otel.express, since it's no
longer technically an otel integration.

Obviously this is not a full clean-room reimplementation, and relies on
the fact that the opentelemetry-js-contrib project is Apache 2.0
licensed. I included the link to the upstream license in the index file
for the Express integration, but there may be a more appropriate way to
ensure that the license is respected properly. It was arguably a
derivative work already, but simple redistribution is somewhat different
than re-implementation with subtly different context.

Closes #19929 (added automatically)

@github-actions
Copy link
Contributor

github-actions bot commented Mar 21, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Deps

  • Bump mongodb-memory-server-global from 10.1.4 to 11.0.1 by dependabot in #19888
  • Bump stacktrace-parser from 0.1.10 to 0.1.11 by dependabot in #19887

Other

  • (core, node) Portable Express integration by isaacs in #19928

Bug Fixes 🐛

Core

  • Do not overwrite user provided conversation id in Vercel by nicohrubec in #19903
  • Return same value from startSpan as callback returns by s1gr1d in #19300

Deps

  • Bump next to 15.5.14 in nextjs-15 and nextjs-15-intl E2E test apps by chargome in #19917
  • Bump socket.io-parser to 4.2.6 to fix CVE-2026-33151 by chargome in #19880

Other

  • (cloudflare) Forward ctx argument to Workflow.do user callback by Lms24 in #19891
  • (craft) Add missing mainDocsUrl for @sentry/effect SDK by bc-sentry in #19860
  • (nestjs) Add node to nest metadata by chargome in #19875
  • (serverless) Add node to metadata by nicohrubec in #19878

Internal Changes 🔧

Deps Dev

  • Bump qunit-dom from 3.2.1 to 3.5.0 by dependabot in #19546
  • Bump @react-router/node from 7.13.0 to 7.13.1 by dependabot in #19544

Other

  • (astro) Re-enable server island tracing e2e test in Astro 6 by Lms24 in #19872
  • (ci) Fix "Gatbsy" typo in issue package label workflow by chargome in #19905
  • (lint) Resolve oxlint warnings by isaacs in #19893
  • (node-integration-tests) Remove unnecessary file-type dependency by Lms24 in #19824
  • (remix) Replace glob with native recursive fs walk by roli-lpci in #19531
  • (sveltekit) Replace recast + @babel/parser with acorn by roli-lpci in #19533
  • Add external contributor to CHANGELOG.md by javascript-sdk-gitflow in #19925
  • Add external contributor to CHANGELOG.md by javascript-sdk-gitflow in #19909

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 21, 2026

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 25.69 kB +0.2% +49 B 🔺
@sentry/browser - with treeshaking flags 24.17 kB +0.14% +33 B 🔺
@sentry/browser (incl. Tracing) 42.67 kB +0.13% +54 B 🔺
@sentry/browser (incl. Tracing, Profiling) 47.33 kB +0.12% +55 B 🔺
@sentry/browser (incl. Tracing, Replay) 81.48 kB +0.08% +57 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 71.06 kB +0.1% +69 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 86.17 kB +0.06% +50 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 98.41 kB +0.04% +36 B 🔺
@sentry/browser (incl. Feedback) 42.48 kB +0.08% +30 B 🔺
@sentry/browser (incl. sendFeedback) 30.35 kB +0.15% +43 B 🔺
@sentry/browser (incl. FeedbackAsync) 35.4 kB +0.12% +39 B 🔺
@sentry/browser (incl. Metrics) 26.96 kB +0.15% +38 B 🔺
@sentry/browser (incl. Logs) 27.1 kB +0.12% +32 B 🔺
@sentry/browser (incl. Metrics & Logs) 27.78 kB +0.15% +39 B 🔺
@sentry/react 27.45 kB +0.22% +58 B 🔺
@sentry/react (incl. Tracing) 45.01 kB +0.14% +60 B 🔺
@sentry/vue 30.13 kB +0.16% +46 B 🔺
@sentry/vue (incl. Tracing) 44.52 kB +0.09% +39 B 🔺
@sentry/svelte 25.7 kB +0.16% +40 B 🔺
CDN Bundle 28.35 kB +0.27% +75 B 🔺
CDN Bundle (incl. Tracing) 43.57 kB +0.15% +62 B 🔺
CDN Bundle (incl. Logs, Metrics) 29.22 kB +0.27% +77 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 44.43 kB +0.17% +75 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 68.29 kB +0.13% +85 B 🔺
CDN Bundle (incl. Tracing, Replay) 80.41 kB +0.1% +73 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 81.31 kB +0.1% +76 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 85.97 kB +0.12% +103 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 86.86 kB +0.1% +86 B 🔺
CDN Bundle - uncompressed 82.7 kB +0.1% +77 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 128.62 kB +0.05% +64 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 85.57 kB +0.1% +77 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 131.49 kB +0.05% +64 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 209.22 kB +0.05% +102 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 245.5 kB +0.04% +89 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 248.35 kB +0.04% +89 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 258.41 kB +0.04% +89 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 261.26 kB +0.04% +89 B 🔺
@sentry/nextjs (client) 47.4 kB +0.08% +37 B 🔺
@sentry/sveltekit (client) 43.12 kB +0.12% +51 B 🔺
@sentry/node-core 56.42 kB +0.15% +80 B 🔺
@sentry/node 173.22 kB +0.04% +68 B 🔺
@sentry/node - without tracing 96.45 kB +0.11% +102 B 🔺
@sentry/aws-serverless 113.45 kB +0.1% +113 B 🔺

View base workflow run

@github-actions
Copy link
Contributor

github-actions bot commented Mar 21, 2026

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 8,844 - 9,535 -7%
GET With Sentry 1,719 19% 1,702 +1%
GET With Sentry (error only) 6,080 69% 6,206 -2%
POST Baseline 1,182 - 1,178 +0%
POST With Sentry 592 50% 560 +6%
POST With Sentry (error only) 1,035 88% 1,042 -1%
MYSQL Baseline 3,144 - 3,199 -2%
MYSQL With Sentry 416 13% 445 -7%
MYSQL With Sentry (error only) 2,561 81% 2,625 -2%

View base workflow run

@isaacs isaacs force-pushed the isaacschlueter/portable-express-integration branch from 3cddcee to dc1b9cf Compare March 21, 2026 23:48
@isaacs isaacs marked this pull request as draft March 21, 2026 23:48
Copy link

@cursor cursor bot left a comment

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 2 potential issues.

Fix All in Cursor

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

@isaacs isaacs force-pushed the isaacschlueter/portable-express-integration branch 3 times, most recently from 6a349bf to ed35ced Compare March 22, 2026 03:42
This extracts the functionality from the OTel Express intstrumentation,
replacing it with a portable standalone integration in `@sentry/core`,
which can be extended and applied to patch any Express module import in
whatever way makes sense for the platform in question.

Currently in node, that is still an OpenTelemetry intstrumentation, but
just handling the automatic module load instrumentation, not the entire
tracing integration.

This is somewhat a proof of concept, to see what it takes to port a
fairly invovled OTel integration into a state where it can support all
of the platforms that we care about, but it does impose a bit less of a
translation layer between OTel and Sentry semantics (for example, no
need to use the no-op `span.recordException()`).

User-visible changes (beyond the added export in `@sentry/core`):

- Express router spans have an origin of `auto.http.express` rather than
  `auto.http.otel.express`, since it's no longer technically an otel
  integration.
- The empty `measurements: {}` object is no longer attached to span
  data, as that was an artifact of otel's `span.recordError`, which is a
  no-op anyway, and no longer executed.

Obviously this is not a full clean-room reimplementation, and relies on
the fact that the opentelemetry-js-contrib project is Apache 2.0
licensed. I included the link to the upstream license in the index file
for the Express integration, but there may be a more appropriate way to
ensure that the license is respected properly. It was arguably a
derivative work already, but simple redistribution is somewhat different
than re-implementation with subtly different context.
@isaacs isaacs force-pushed the isaacschlueter/portable-express-integration branch from 88eeb84 to 8753cac Compare March 22, 2026 06:44
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.

feat(core, node): portable Express integration

1 participant