feat(instrumentation): add opt-in console log capture - #2469
feat(instrumentation): add opt-in console log capture#2469Abhijeet Prasad (AbhiPrasad) wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9ebe3ef28b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".
| } | ||
| } | ||
| } finally { | ||
| state.forwarding = false; |
There was a problem hiding this comment.
Exclude asynchronous SDK diagnostics from console capture
When console capture includes warn and Braintrust debug logging is enabled, a background upload failure causes HTTPBackgroundLogger to emit debugLogger.warn() after this synchronous forwarding guard has already been cleared. That warning is captured and enqueued into the same failing logger; subsequent flushes—especially repeated Node beforeExit flushes—produce replacement warning rows and can keep retrying indefinitely. SDK diagnostics need to bypass the patched console methods or otherwise remain suppressed for asynchronous logger work.
AGENTS.md reference: AGENTS.md:L32-L36
Useful? React with 👍 / 👎.
| notifyHandlers(level, args); | ||
| return original.apply(this, args); |
There was a problem hiding this comment.
Invoke the original console method before formatting arguments
In Node, when a logged object has a stateful toJSON, getter, or proxy trap, notifyHandlers() serializes it before original.apply(), so instrumentation code can mutate the argument before the real console observes it. For example, a toJSON() that changes this.value causes console.log(object) to display the changed value only when instrumentation is enabled, contradicting the promised unchanged console behavior; invoke the original method before forwarding.
AGENTS.md reference: AGENTS.md:L32-L36
Useful? React with 👍 / 👎.
| if (state.wrappers.has(level)) { | ||
| continue; |
There was a problem hiding this comment.
Reinstall console wrappers that have been replaced
If another library, test spy, or application cleanup later replaces console.log, the stored wrapper-map entry remains forever even after all registrations stop. A subsequent explicit instrumentConsole() call therefore skips this level although the installed method is no longer the Braintrust wrapper, so calls are silently not captured; compare the current console method with the stored wrapper and re-chain the current method when they differ.
AGENTS.md reference: AGENTS.md:L32-L36
Useful? React with 👍 / 👎.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Add `instrumentConsole()` to forward console calls through the current project
logger while preserving their original behavior. Callers can select levels and
stop forwarding with the returned cleanup function:
initLogger({ projectName: "my-project" });
const stop = instrumentConsole({ levels: ["warn", "error"] });
console.warn("Retrying payment", { attempt: 2 });
console.error("Payment failed");
stop();
Support console substitutions, safe object and error formatting, failed
assertions, repeated setup, and both synchronous and asynchronous loggers.
Contain instrumentation failures so console calls continue unchanged.
9ebe3ef to
7c9afd9
Compare
Add
instrumentConsole()to forward console calls through the current projectlogger while preserving their original behavior. Callers can select levels and
stop forwarding with the returned cleanup function: