Skip to content

feat(mongoose): Instrument mongoose >= 9.7 via native tracing channels#21803

Merged
logaretm merged 7 commits into
developfrom
awad/mongoose-tracing-channels
Jul 2, 2026
Merged

feat(mongoose): Instrument mongoose >= 9.7 via native tracing channels#21803
logaretm merged 7 commits into
developfrom
awad/mongoose-tracing-channels

Conversation

@logaretm

@logaretm logaretm commented Jun 25, 2026

Copy link
Copy Markdown
Member

Instruments mongoose >= 9.7 through its native diagnostics_channel tracing channels instead of monkey-patching, the same way we did for redis/ioredis. The subscription lives in server-utils as mongooseChannelIntegration, and the node mongooseIntegration extends it (via extendIntegration) to keep running the IITM patcher for mongoose < 9.7.

The channel path emits the latest stable DB semconv, so there is an attribute drift. We did that for redis so I thought to do the same here, but we could match the legacy attributes and drop them later for v11 if that's what we want.

@logaretm logaretm force-pushed the awad/mongoose-tracing-channels branch from 668581c to 0e1e4c1 Compare June 25, 2026 17:26
@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 27.59 kB - -
@sentry/browser - with treeshaking flags 26.03 kB - -
@sentry/browser (incl. Tracing) 46.05 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 47.79 kB - -
@sentry/browser (incl. Tracing, Profiling) 50.81 kB - -
@sentry/browser (incl. Tracing, Replay) 85.28 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 74.89 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 89.97 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 102.64 kB - -
@sentry/browser (incl. Feedback) 44.77 kB - -
@sentry/browser (incl. sendFeedback) 32.39 kB - -
@sentry/browser (incl. FeedbackAsync) 37.52 kB - -
@sentry/browser (incl. Metrics) 28.67 kB - -
@sentry/browser (incl. Logs) 28.91 kB - -
@sentry/browser (incl. Metrics & Logs) 29.6 kB - -
@sentry/react 29.38 kB - -
@sentry/react (incl. Tracing) 48.35 kB - -
@sentry/vue 32.82 kB - -
@sentry/vue (incl. Tracing) 47.91 kB - -
@sentry/svelte 27.61 kB - -
CDN Bundle 30 kB - -
CDN Bundle (incl. Tracing) 47.98 kB - -
CDN Bundle (incl. Logs, Metrics) 31.57 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.32 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 70.77 kB - -
CDN Bundle (incl. Tracing, Replay) 85.48 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 86.76 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 91.29 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.53 kB - -
CDN Bundle - uncompressed 89.35 kB - -
CDN Bundle (incl. Tracing) - uncompressed 145.28 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 94.05 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 149.25 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 218.59 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 264.29 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 268.25 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 277.99 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 281.94 kB - -
@sentry/nextjs (client) 50.73 kB - -
@sentry/sveltekit (client) 46.44 kB - -
@sentry/core/server 77.75 kB - -
@sentry/core/browser 64.06 kB - -
@sentry/node-core 62.37 kB - -
@sentry/node 121.67 kB +0.36% +425 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 69.95 kB - -
@sentry/node/light 50.46 kB - -
@sentry/node - without tracing 72.68 kB - -
@sentry/aws-serverless 83.52 kB -0.01% -1 B 🔽
@sentry/cloudflare (withSentry) - minified 180.62 kB - -
@sentry/cloudflare (withSentry) 446.93 kB - -

View base workflow run

@mydea

mydea commented Jun 26, 2026

Copy link
Copy Markdown
Member

mongooseChannelIntegration

more a general thing, but I think I'd just call this mongooseIntegration? When using this from server-utils this is kind of an implementation detail that is not that relevant, you can just use the integration from there? It's a bit different for the orchestrion ones because they should not be "accidentally" used, but for these with native support I think just calling them "normally" is fine?

@mydea mydea force-pushed the fn/better-integration-extend branch 2 times, most recently from 2407b9e to 31520be Compare June 26, 2026 08:48
Base automatically changed from fn/better-integration-extend to develop June 26, 2026 09:38
@logaretm

Copy link
Copy Markdown
Member Author

Yea I was thinking about this yesterday, we ideally would export those as-is for the environments that do not support module hooks. Will make that change

@logaretm logaretm force-pushed the awad/mongoose-tracing-channels branch from 5a990f3 to 3e8b992 Compare June 26, 2026 11:49
@logaretm logaretm marked this pull request as ready for review June 26, 2026 12:55
@logaretm logaretm requested a review from a team as a code owner June 26, 2026 12:55
@logaretm logaretm requested review from JPeer264, andreiborza, isaacs, mydea and nicohrubec and removed request for a team June 26, 2026 12:55
@logaretm logaretm force-pushed the awad/mongoose-tracing-channels branch from ccbdd92 to 9cbf9df Compare June 26, 2026 13:01

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 1 potential issue.

Fix All in Cursor

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

Reviewed by Cursor Bugbot for commit 9cbf9df. Configure here.

instrumentMongoose();
},
};
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preload skips mongoose channel subscribe

Medium Severity

For mongoose >=9.7, diagnostics-channel subscription runs only in the server-utils integration setupOnce, while preloadOpenTelemetry invokes instrumentMongoose alone. The IITM patcher no longer covers 9.7+, so mongoose work between preload and Sentry.init() (or any preload-only usage) is not traced.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9cbf9df. Configure here.

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.

I think that is ok.

@JPeer264 JPeer264 left a comment

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.

Code wise LGTM. I think this one has not been done yet? #21803 (comment) (I would vote for that too)

...(collection != null ? { [DB_COLLECTION_NAME]: collection } : {}),
...(data.database != null ? { [DB_NAMESPACE]: data.database } : {}),
...(queryText != null ? { [DB_QUERY_TEXT]: queryText } : {}),
...(batchSize != null ? { [DB_OPERATION_BATCH_SIZE]: batchSize } : {}),

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.

l: undefined values are skipped, null not, so it seems like this was done on purpose. I think following is a little easier to read:

Suggested change
...(batchSize != null ? { [DB_OPERATION_BATCH_SIZE]: batchSize } : {}),
[DB_OPERATION_BATCH_SIZE]: batchSize ?? undefined

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, that was ugly

logaretm added 7 commits July 1, 2026 13:11
Subscribe to mongoose 9.7's native diagnostics_channel tracing channels via
bindTracingChannelToSpan, emitting stable OTel DB semconv. Narrow the vendored
OTel patcher to < 9.7.0 to avoid double instrumentation.
…gration

Runtimes that use the server-utils integration directly expose it to users,
so 'channel' in the name leaks an implementation detail. Node imports it under
an internal alias since it keeps its own composed mongooseIntegration.
Replace the conditional-spread pattern for optional attributes with
`?? undefined`. Undefined-valued keys are dropped by the span backends,
so this is equivalent while keeping all six attribute lines consistent.
Replace the ad-hoc `void Promise.resolve().then(...)` deferral with the
shared `waitForTracingChannelBinding` util, matching the vercel-ai and
redis integrations. It retries until the async context binding is
available, so it also handles custom OTel setups where the binding isn't
ready on the first tick.
@logaretm logaretm force-pushed the awad/mongoose-tracing-channels branch from 9cbf9df to 6e85b2f Compare July 1, 2026 17:13
@logaretm logaretm merged commit 0c33a8d into develop Jul 2, 2026
372 of 376 checks passed
@logaretm logaretm deleted the awad/mongoose-tracing-channels branch July 2, 2026 15:47
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.

3 participants