-
Type:
New Feature
-
Resolution: Unresolved
-
Priority:
Unknown
-
None
-
Affects Version/s: None
-
Component/s: Logging
-
None
-
None
-
None
-
None
-
None
-
None
I'd like to propose adding first-class TracingChannel support to the MongoDB Node.js driver, following the pattern established by [undici|https://github.com/nodejs/undici] in Node.js core.
The MongoDB driver already has an excellent observability foundation via command monitoring.
However, APM instrumentation libraries (OpenTelemetry, Datadog, Sentry) {}do not use these events{} for span-based tracing today. Instead, they resort to monkey-patching internal methods like `Connection.prototype.command` and `ConnectionPool.prototype.checkOut` via IITM/RITM. Here's why:
1. {}No async context propagation.{} Command Monitoring events are emitted via `EventEmitter`. When `commandStarted` fires, the listener runs in the emitter's execution context — not the caller's `AsyncLocalStorage` context. APM tools need to create child spans of the caller's span, which requires capturing the async context at the call site. EventEmitter listeners lose this context.
2. {}Opt-in gating.{} Command Monitoring only fires when the user passes `monitorCommands: true` to `MongoClient`. APM tools can't control how users instantiate their clients, so they can't rely on this flag being set. Monkey-patching works regardless of user configuration.
3. {}Split lifecycle.{} `commandStarted` and `commandSucceeded`/`commandFailed` are separate EventEmitter events. To build a span, APM tools must correlate them via `requestId` and manage span storage manually. Tracing channels provide a contextualized lifecycle for the operation, so correlation is built-in.
Beyond these APM-specific gaps, the current monkey-patching approach has broader ecosystem concerns:
- Runtime lock-in: RITM and IITM rely on Node.js-specific module loader internals (`Module._resolveFilename`, `module.register()`). They don't work on Bun or Deno, which implement the Node.js API surface but not the module loader internals.
- ESM fragility: IITM is built on Node.js's module customization hooks, which are still evolving and have been a persistent source of breakage in the OTEL JS ecosystem.
- Initialization ordering: Both require instrumentation to be set up before `mongodb` is first `require()`'d / `import`'d. Get the order wrong and instrumentation silently does nothing — very hard to debug in production.
- Bundling: Users must ensure instrumented modules are externalized, which is increasingly difficult as frameworks bundle server-side code into single executables or deployment files.
`TracingChannel` solves all of these. It provides structured lifecycle events (`start`, `end`, `asyncStart`, `asyncEnd`, `error`) with built-in async context propagation, zero-cost when no subscribers are attached, and a standardized subscription model that requires no monkey-patching.
The driver's existing Command Monitoring and CMAP events remain valuable for operational monitoring and debugging. `TracingChannel` is not a replacement, it's a complement that fills the specific gaps APM tools need for span-based distributed tracing.
I'm happy to collaborate on this with your team if you think it's a worthwhile improvement.