perf(cli): stop session logs growing by tens of MB a day - #1745
Open
chphch wants to merge 1 commit into
Open
Conversation
Two writers dominated ~1.3 GB of session logs on one machine, neither of
them carrying information anyone reads.
`logToFile` inspects every non-string argument at depth 5. Any error thrown
by a failed HTTP or socket.io call transitively holds a Node socket, so a
single `logger.debug('...', err)` expanded into hundreds of lines of TLS
cipher lists and internal symbols — 55% of all bytes written. Cap one
inspected argument at 4000 chars, which keeps the error's own top-level
fields and drops the object graph behind them.
`sessionScanner` logged the file it was about to read and a scan summary on
every 3s poll, for the whole life of a session — ~2400 identical lines an
hour, 32% of all bytes. Log state changes instead: report an absent
transcript once per absence rather than once per tick, and write the scan
summary when the poll actually moved something, otherwise at most once a
minute so liveness stays observable.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two writers dominate a Happy CLI session log, and neither carries anything a reader uses.
logToFileinspects every non-string argument atdepth: 5, so a singlelogger.debug('...', err)on an error that transitively holds a Node socket — which every failed HTTP or socket.io call produces — expands into hundreds of lines of TLS cipher lists and internal symbols. Separately,sessionScannerwrites the path it is about to read plus a scan summary on every 3-second poll, for the entire life of a session, which is ~2400 identical lines an hour whether or not anything changed. On my machine~/.happy/logshad reached 1.3 GB, with individual week-old sessions holding 80–90 MB each; measured across those files, the object dumps were 55% of all bytes written and the scanner's repeated lines another 32%.This does not add a log level or a config knob — it stops writing bytes nobody reads:
Proof
No UI surface, so this is measured rather than filmed.
Steady-state growth, two idle sessions on the same machine over the same 180 s window — one still on the pre-patch binary, one on the patched build:
The patched session's log shows the summary line at 60-second spacing (
08:06:34,08:07:34,08:08:35) where the pre-patch one still writes aReading session file:plus a summary every 3 s.Truncation, against a real object of the kind that filled the logs (a live
httpsresponse, which holds a TLS socket):packages/happy-clitsc --noEmitis clean and thesessionScanner+startFileWatchersuites pass. I have been running this on my own daily-driver instance since building it, which is where the 180 s comparison above was taken.The two halves are independent and I am happy to split them into separate PRs if you would rather review them apart — they are together here because they were found by the same measurement of the same file.