diagnostics_channel: add opt-in subscriber suppression via bypassBy and bypassed()#63651
diagnostics_channel: add opt-in subscriber suppression via bypassBy and bypassed()#63651DivyanshuX9 wants to merge 35 commits into
Conversation
Defer non-critical warnings to the next event loop iteration when can_call_into_js() returns false. This prevents crashes when V8 emits warnings during REPL preview evaluation or other contexts where JavaScript execution is temporarily forbidden. When a warning is emitted inside DisallowJavascriptExecutionScope, ProcessEmitWarningGeneric cannot be called immediately. Instead, use env->SetImmediate() to queue the warning emission for after the scope exits. This preserves full warning formatting, deprecation codes, and --redirect-warnings routing. Signed-off-by: Divyanshu Sharma <Divyanshu88999@gmail.com>
Refs: nodejs#63623 Refs: nodejs#63651 Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
5b4110a to
8b122c2
Compare
Refs: nodejs#63623 Refs: nodejs#63651 Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
Refs: nodejs#63623 Refs: nodejs#63651 Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
8b122c2 to
e4aea85
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #63651 +/- ##
==========================================
+ Coverage 90.21% 90.24% +0.02%
==========================================
Files 741 741
Lines 241608 241755 +147
Branches 45534 45557 +23
==========================================
+ Hits 217972 218177 +205
+ Misses 15154 15148 -6
+ Partials 8482 8430 -52
🚀 New features to boost your workflow:
|
Qard
left a comment
There was a problem hiding this comment.
Tests are missing a lot of necessary common.mustCall(fn) wrappers.
Also, it seems like this was just vibe-coded without reviewing the output before submitting the PR. Please ensure it is in a good state and that the test suite and lint passes before submitting.
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
…update tests to use common.mustCall
|
@Qard , thanks for the detailed review. So far the checklist of what i have fixed in the latest push: [] Removed the impossible ALS try/catch fallback Ready for re-review and any changes if you want, when you have time please review it. |
0f6e780 to
8fa6fd8
Compare
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
8fa6fd8 to
b8194af
Compare
|
The node_errors.cc change still seems to be present. |
…ove SetImmediate deferral) Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
|
@bengl both items from your review are addressed. On the TracingChannel side, I deep-dived into this, and the per subscriber bypassId already works in TracingChannel without any additional code in traceSync, tracePromise, or traceCallback because the bypassId gets passed from TracingChannel.subscribe() down through BoundedChannel.subscribe() to its underlying Channel.subscribe() where it’s stored in _bypassSubscribers. All code paths in the 3 trace methods will hit ActiveChannel.publish() which performs the per handler bypassId check including the async continuations in tracePromise and traceCallback. Same for stores via RunStoresScope. I also added tests 11, 12, and 13 to verify this for traceSync, tracePromise, and traceCallback, all tests 11-13 pass. Tests 12 & 13 specifically provide coverage for async boundaries to ensure bypass context is propagated correctly through the continuation window. A note of caution: the convenience function subscribe(name, fn) does NOT support options in this PR, and bypassId would only be accessible via the instance API (ch.subscribe(fn, { bypassId })). This is done on purpose as bypass is essentially an advanced APM vendor feature and those vendors are already using the instance API pattern. If the team would like, I would be glad to add options support to the module-level helpers in a subsequent PR. What could make sense as next steps from here: -Docs update in doc/api/diagnostics_channel.md covering bypass() and the bypassId option with a real-world APM example. -Mirroring this in dc-polyfill so Bun and Deno users aren't stuck waiting for runtime support. Happy to pick up any of those or adjust anything here based on your feedback. |
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
|
@bengl @BridgeAR
Still waiting on your re-review when you have time. Let me know if there's anything specific blocking approval so I can address it. |
|
@DivyanshuX9 Thanks for the additional details. I was trying to figure out whether Additional docs are definitely needed though. |
|
I think implementation + tests + docs of a new public API should come in one PR. |
|
@Flarna Well once BridgeAR also mentioned about doc
at that time was not sure how far reviews will go ,also @rochdev wanted some examples rightaway, So made a seperate PR for that to keep this one clean , yes if i get a green signal to land this one will will update and merge that pr doc in this one. |
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
|
@Flarna i have moved all the docs here |
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
2ba3a7a to
f7f593e
Compare
|
@Flarna , lowkey I have addressed all feedback in latest push:
Thank you for the thorough review. |
also @Flarna at 251 line is this correct or should i just remove REPLACE ME with the stability:1.1 right away |
|
No, the The stability index is just documentation and independent of that. |
Signed-off-by: Divyanshu Sharma <divyanshu88999@gmail.com>
2fccc37 to
58785bb
Compare
|
@BridgeAR following up on your performance concern, ran a microbenchmark on the normal-subscriber hot path (1,000,000 iterations, no bypass() active):
Test 1 is the pure normal path with no bypass subscriber registered at all, the overhead is just the _bypassSubscribers !== null null-check plus the extra fields on the channel object, comes out to around 2.2ns per call.
|


Summary
Adds opt-in subscriber suppression to
diagnostics_channelso APMagents can prevent recursive instrumentation when their own internal
code calls into instrumented libraries.
What Changed
lib/diagnostics_channel.jssuppressed(key, fn, thisArg, ...args)- runsfnwiththe given key active in the current async context
subscribe()andbindStore()accept{ subscriberId }optionpath has zero overhead, ALS is only hit when bypass subscribers exist
AsyncLocalStorageinitialization viagetSuppressionsStorage()async_hooks is available
validateBypassKey()helper for all key validationtest/parallel/test-diagnostics-channel-suppression.jsstore, nested, and type validation cases
Why
APM agents currently implement suppression themselves using a
custom ALS noop marker - every vendor reimplements the same
pattern differently. Moving it into core:
Backward Compatibility
Naming
As per @bengl final name is "Bypass"
Addresses:#63623