Skip to content

feat(node): Implement registerModuleWrapper as alternative IITM/RITM wrapping method#20188

Draft
mydea wants to merge 3 commits intodevelopfrom
fn/custom-iitm-wrapping
Draft

feat(node): Implement registerModuleWrapper as alternative IITM/RITM wrapping method#20188
mydea wants to merge 3 commits intodevelopfrom
fn/custom-iitm-wrapping

Conversation

@mydea
Copy link
Copy Markdown
Member

@mydea mydea commented Apr 10, 2026

Part of #20171

This PR implements a new method in node-core:

registerModuleWrapper<OptionsType>({
  moduleName: 'express',
  supportedVersions: ['>=4<6'],
  options,
  patch: (moduleExports, getOptions) => {
    wrapExpressModule(moduleExports, getOptions);
  }
});

This works similarly to otel wrapping, registering the patch with IITM and RITM using the same semantics, more or less. It is a bit simplified for our requirements but should generally behave the same.

registerModuleWrapper is designed to be idempotent and to be callable multiple times. It will only actually patch once, calling it subsequently will update the options though - any options required in the patch should be resolved at runtime (!) via the passed-in getOptions. (Why, you may ask yourself? Because we rely on this for preloading OTEL instrumentation, where we run the patch in --import preload.ts or similar but do not have the options yet, which are defined later in init(), but should update the instrumentation config accordingly).

I have tentatively implemented this for the existing express instrumentation. This is def. a breaking change so nothing we can ship now but it should show how this can/should eventually look.

Note that this should not be merged as it is a breaking change and only for showcase & discussion how this can/should work.

@mydea mydea self-assigned this Apr 10, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 10, 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 ✨

Core

  • Add enableTruncation option to OpenAI integration by andreiborza in #20167
  • Export a reusable function to add tracing headers by JPeer264 in #20076

Other

  • (deps) Bump defu from 6.1.4 to 6.1.6 by dependabot in #20104
  • (node) Implement registerModuleWrapper as alternative IITM/RITM wrapping method by mydea in #20188

Internal Changes 🔧

  • (size-limit) Bump failing size limit scenario by Lms24 in #20186

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 10, 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.72 kB +0.31% +77 B 🔺
@sentry/browser - with treeshaking flags 24.21 kB +0.34% +82 B 🔺
@sentry/browser (incl. Tracing) 42.73 kB +1.36% +573 B 🔺
@sentry/browser (incl. Tracing, Profiling) 47.35 kB +1.25% +583 B 🔺
@sentry/browser (incl. Tracing, Replay) 81.54 kB +0.75% +600 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 71.11 kB +0.78% +549 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 86.25 kB +0.7% +594 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 98.45 kB +0.56% +541 B 🔺
@sentry/browser (incl. Feedback) 42.51 kB +0.21% +87 B 🔺
@sentry/browser (incl. sendFeedback) 30.39 kB +0.27% +80 B 🔺
@sentry/browser (incl. FeedbackAsync) 35.38 kB +0.24% +82 B 🔺
@sentry/browser (incl. Metrics) 27.04 kB +0.31% +83 B 🔺
@sentry/browser (incl. Logs) 27.18 kB +0.3% +81 B 🔺
@sentry/browser (incl. Metrics & Logs) 27.86 kB +0.29% +80 B 🔺
@sentry/react 27.48 kB +0.26% +71 B 🔺
@sentry/react (incl. Tracing) 45.05 kB +1.28% +566 B 🔺
@sentry/vue 30.56 kB +1.61% +483 B 🔺
@sentry/vue (incl. Tracing) 44.59 kB +1.23% +538 B 🔺
@sentry/svelte 25.74 kB +0.31% +77 B 🔺
CDN Bundle 28.41 kB +0.3% +83 B 🔺
CDN Bundle (incl. Tracing) 43.75 kB +1.46% +628 B 🔺
CDN Bundle (incl. Logs, Metrics) 29.78 kB +0.31% +92 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 44.83 kB +1.5% +660 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 68.59 kB +0.16% +103 B 🔺
CDN Bundle (incl. Tracing, Replay) 80.64 kB +0.78% +621 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 81.66 kB +0.75% +604 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 86.17 kB +0.72% +615 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 87.2 kB +0.71% +610 B 🔺
CDN Bundle - uncompressed 82.99 kB +0.34% +279 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 129.77 kB +1.5% +1.92 kB 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 87.14 kB +0.33% +279 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 133.19 kB +1.46% +1.92 kB 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 210.12 kB +0.14% +279 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 246.65 kB +0.79% +1.92 kB 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 250.05 kB +0.78% +1.92 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 259.56 kB +0.75% +1.92 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 262.95 kB +0.74% +1.92 kB 🔺
@sentry/nextjs (client) 47.47 kB +1.24% +579 B 🔺
@sentry/sveltekit (client) 43.2 kB +1.36% +577 B 🔺
@sentry/node-core 57.86 kB +3.78% +2.1 kB 🔺
⛔️ @sentry/node (max: 177 kB) 187.73 kB +8.9% +15.33 kB 🔺
@sentry/node - without tracing 97.97 kB +2.02% +1.94 kB 🔺
@sentry/aws-serverless 115.22 kB +2.11% +2.38 kB 🔺

View base workflow run

@mydea mydea force-pushed the fn/custom-iitm-wrapping branch from 6c2f752 to 9192a07 Compare April 10, 2026 08:38
@github-actions
Copy link
Copy Markdown
Contributor

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.
⚠️ 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.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 9,113 - 14,229 -36%
GET With Sentry 1,836 20% 2,638 -30%
GET With Sentry (error only) 6,182 68% 9,829 -37%
POST Baseline 1,218 - 1,627 -25%
POST With Sentry 599 49% 855 -30%
POST With Sentry (error only) 1,046 86% 1,425 -27%
MYSQL Baseline 3,248 - 4,517 -28%
MYSQL With Sentry 515 16% 548 -6%
MYSQL With Sentry (error only) 2,648 82% 3,802 -30%

View base workflow run

* and ModuleNameTrie. It provides a single RITM hook with trie-based module name matching
* for better performance when using many module wrappers.
*
* OpenTelemetry: Copyright The OpenTelemetry Authors - Apache-2.0
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.

(nit, I know this is still obviously wip) Guidance from legal is to include the longer license disclaimer with the link and "PROVIDED AS IS" bit, like we do in packages/core/src/integrations/express.

/* eslint-disable no-param-reassign */

import * as path from 'node:path';
import { Hook } from 'require-in-the-middle';
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.

Presumably we'll also need a version of this for iitm, and also need to pull the relevant guts out for use in Bun, right?

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.

Oh, wait, nevermind, this is node-core, not core, so no bun stuff. But we do need IITM.

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