feat: spool records to a file store with a CRC-16 at rest - #38
Conversation
A SolidSyslogBlockStore over a FileBlockDevice over the library's FatFs port, replacing the Null store. The service task drains the ring into the store and sends from there, so a failed send costs a retry rather than the record. Flash +11,576 B (+3,964 on the previous stage) RAM +7,092 B (+1,212) Log stack +448 B (unchanged) Service +736 B (+64) The log stack does not move: storing happens on the service task, and a task that calls Log still knows nothing about what happens after it returns. The service task's own high-water rises 64 bytes to 788, which the 2 KiB seam the buffered stage sized absorbs, so no RAM moves with it. The static RAM is pool allocation, not buffers. The 8192-byte block size is file capacity — nothing holds a block in memory, so the store costs its handles rather than its capacity. CRC-16 is a checksum, not tamper-evidence: it catches a truncated write or bit-rot, and anyone who can edit a stored record can recompute it. What it buys is knowing a record came back the way it went in, which is the prerequisite for spooling at all. One file per block, syslog00.log upward on the volume the device already mounts, four blocks, oldest discarded when full — a device that cannot reach its collector should keep the newest evidence rather than stop logging. SolidSyslog::FatFs is a header-configured upstream, so it is named in SOLIDSYSLOG_PLATFORMS and linked. The discard policy enumerator is SOLIDSYSLOG_DISCARD_POLICY_OLDEST. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe change enables FatFs, replaces the null syslog store with CRC16-protected file-backed block storage, and updates documentation and measurement reports for the file-store configuration. ChangesFile store integration
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Syslog_Start
participant SolidSyslogBlockStore
participant FatFsFileBlockDevice
Syslog_Start->>FatFsFileBlockDevice: configure persistent block storage
Syslog_Start->>SolidSyslogBlockStore: create store with discard-oldest and CRC16 policies
SolidSyslogBlockStore-->>Syslog_Start: provide configured Store
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review The previous run on this PR came back rate limited rather than completed, so this PR has not actually been reviewed. Please run a full review. |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/syslog/Syslog.c (1)
125-137: 🗄️ Data Integrity & Integration | 🔵 Trivial | 🏗️ Heavy liftExercise the file-store failure paths in validation.
Add or confirm integration coverage for failed-send retry, reboot recovery, CRC rejection, and oldest-block discard when the four-block limit is reached. The supplied run output proves successful delivery and measurements, but not these persistence guarantees.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/syslog/Syslog.c` around lines 125 - 137, Extend integration validation around SolidSyslogBlockStore_Create and the configured storeConfig to cover failed-send retry, reboot recovery, CRC rejection, and oldest-block discard once MaxBlocks reaches the four-block limit. Exercise each persistence scenario and assert the expected retained, recovered, or rejected records rather than only successful delivery and measurements.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@app/syslog/Syslog.c`:
- Around line 125-137: Extend integration validation around
SolidSyslogBlockStore_Create and the configured storeConfig to cover failed-send
retry, reboot recovery, CRC rejection, and oldest-block discard once MaxBlocks
reaches the four-block limit. Exercise each persistence scenario and assert the
expected retained, recovered, or rejected records rather than only successful
delivery and measurements.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ff55e4c3-31cc-42a2-b586-9b3ca04f4f44
⛔ Files ignored due to path filters (2)
measurements/file-store.csvis excluded by!**/*.csvmeasurements/stages.tsvis excluded by!**/*.tsv
📒 Files selected for processing (4)
CMakeLists.txtREADME.mdapp/syslog/Syslog.crun-report.md
Pull request
What this stage adds
A SolidSyslogBlockStore over a FileBlockDevice over the library's FatFs port,
replacing the Null store. The service task drains the ring into the store and sends
from there, so a failed send costs a retry rather than the record.
Flash +11,576 B (+3,964 on the previous stage)
RAM +7,092 B (+1,212)
Log stack +448 B (unchanged)
Service +736 B (+64)
The log stack does not move: storing happens on the service task, and a task that
calls Log still knows nothing about what happens after it returns. The service
task's own high-water rises 64 bytes to 788, which the 2 KiB seam the buffered
stage sized absorbs, so no RAM moves with it.
The static RAM is pool allocation, not buffers. The 8192-byte block size is file
capacity — nothing holds a block in memory, so the store costs its handles rather
than its capacity.
CRC-16 is a checksum, not tamper-evidence: it catches a truncated write or bit-rot,
and anyone who can edit a stored record can recompute it. What it buys is knowing a
record came back the way it went in, which is the prerequisite for spooling at all.
One file per block, syslog00.log upward on the volume the device already mounts,
four blocks, oldest discarded when full — a device that cannot reach its collector
should keep the newest evidence rather than stop logging.
SolidSyslog::FatFs is a header-configured upstream, so it is named in
SOLIDSYSLOG_PLATFORMS and linked. The discard policy enumerator is
SOLIDSYSLOG_DISCARD_POLICY_OLDEST.
Files
Checklist
measurements/file-store.csvcommitted.measurements/stages.tsv.python3 scripts/gen-cost-table.py../run.shgreen (build + QEMU + baseline self-check) —run-report.mdcommitted.Context for review: 11 of 21 sequential single-commit PRs replaying the integration on top of the Baseline root. Each lands green and reviewed before the next is built on it, because a change to an early commit would force every commit above it to be re-run and re-measured.
Summary by CodeRabbit
New Features
Documentation