chadtmiller.com/knotless
git that lives in your Atmosphere account
1
10
Reading the logs by message walks that message's index
Merged Approved
This splits Logs::read into three statements: by trace, by message, and by level or duration alone. The message statement uses INDEXED BY line_message, and that index is created in the schema at logs.rs:68 on (message, id). So message = ?2 ... ORDER BY id DESC should walk the index newest first and stop at the limit. I found no bugs.
- Parameters: the shared
params!list still binds all five values, as the old trace statement already did with its unused ones. This is fine. - Trace reads: a trace read still ignores
message, as it did before. INDEXED BY: it errors if the index is missing. Here the index is created withIF NOT EXISTS, so that shouldn't happen.- Tests: I didn't confirm that
keeps_reads_and_lets_gocovers the by-message path, and I didn't check CI. Your plan to time the prod read after deploy is a good check.
All checks have passed
8 passed, 2 skipped
Merged as cf8fb93
What changes
Logs::readnow uses a separate statement for each way of asking. A read by trace is unchanged. A read by message walksline_message (message, id)newest first, its level and duration filters checked on the way. A read by level or duration alone walks the table newest first, as before.Why
There used to be one statement for every filter, with the message test written
(?2 IS NULL OR message = ?2), and no index can answer that. A read by message walked every line kept, up to 30 days of them, newest first, until it had enough. A common message such asrequeststops early, but a rare one reads nearly the whole table. On prod, the first read of the newly loggedmcp toollines took 9.0s ingetLogs, while the store held one such line.How it was checked
keeps_reads_and_lets_goalready reads by trace, message, level and duration, so it covers each statement. The rest is left to CI. Once this is deployed, I'll time agetLogsread ofmessage=mcp toolagain on prod: it was 9.0s before.Shortcomings
A read by a rare level or a long
minMsalone still walks lines newest first until it has enough. An index onmswould only help if reads used it in place of the newest-first order, and slow lines are common enough that the walk ends soon.🤖 Generated with Claude Code