diff --git a/src/index.ts b/src/index.ts index fc3a701c..efa84fa5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,11 +5,30 @@ const _origConsoleError = console.error const _origConsoleLog = console.log const _origConsoleInfo = console.info +const _origConsoleWarn = console.warn + +// Suppress libsignal session lifecycle dumps from console.log / console.info / console.warn. +// libsignal's session_record.js / session_builder.js / session_cipher.js use: +// console.info("Removing old closed session:", obj) ← ~500ms I/O dump per call +// console.info("Opening session:", obj) ← ~500ms I/O dump per call +// console.info("Migrating session to:", v) ← per migration +// console.log("Closing session:", obj) ← ~500ms I/O dump per call +// console.warn("Closing open session in favor of incoming prekey bundle") ← per pkmsg +// console.warn("Session already closed", obj) ← per stale close +// console.warn("Decrypted message with closed session.") ← per recovered decrypt +// console.warn("Unhandled bucket type (for naming):", ...) ← queue_job edge case +// +// Under WhatsApp's LID/DSM rollout these fire dozens of times per minute when +// the auth state has legacy `_1.0` sessions that don't match LID-addressed +// envelopes. Each dump is a synchronous stdout.write — pm2 buffers fill and +// the event loop blocks. Symptom: 60s inbound delivery latency, profile +// pictures don't load, queries time out. +// +// The clean operator-facing signal lives in the console.error interceptor +// below (formats Bad MAC / Counter / Decryption Failed as one emoji line). +const _SESSION_LIFECYCLE_RE = + /^(Closing session|Removing old closed session|Opening session|Migrating session|Closing open session|Session already closed|Decrypted message with closed session|Unhandled bucket type)/ -// Suppress libsignal session lifecycle dumps from console.log / console.info. -// libsignal's session_record.js uses console.info("Removing old closed session:", obj) -// and console.log("Closing session:", obj) which dump full session objects (~500ms I/O each). -const _SESSION_LIFECYCLE_RE = /^(Closing session|Removing old closed session)/ console.log = function (...args: unknown[]) { if (args.length > 0 && typeof args[0] === 'string' && _SESSION_LIFECYCLE_RE.test(args[0])) { return @@ -26,6 +45,14 @@ console.info = function (...args: unknown[]) { _origConsoleInfo.apply(console, args) } +console.warn = function (...args: unknown[]) { + if (args.length > 0 && typeof args[0] === 'string' && _SESSION_LIFECYCLE_RE.test(args[0])) { + return + } + + _origConsoleWarn.apply(console, args) +} + // Track errors by type + JID to avoid duplicates (using Map for better performance) const _errorTimestamps = new Map() // Dedup window for repeated decrypt-error console lines (Bad MAC / Counter / etc).