feat: periodically checkpoint server/sud logs to disk

Both loggers previously only wrote their JSON log on their end trigger
(shutdown / Stop-or-DONE), losing the whole session/run's data on a
hard crash or power loss. Add a log_interval (config.json, default
300s) that rewrites the same file whole every N seconds in between.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvgC7oy9MxaA4ZQxXqkNdS
This commit is contained in:
2026-07-01 09:44:11 +02:00
co-authored by Claude Sonnet 5
parent d3c8a47562
commit 0e60860cf0
6 changed files with 38 additions and 15 deletions
+10 -8
View File
@@ -689,20 +689,22 @@ Both loggers record the same six signals the GUI's Automatic tab plots live
(`temp_ist`/`temp_soll`, `rate_ist`/`rate_soll`, `power_set`/`power_eff`),
each sample with both simulated-elapsed-seconds and a real wall-clock
timestamp, plus any plant-param changes along the way (see
`apply_plant_params()`) - written as JSON via `write()`, whole and only
once, never partially mid-run.
`apply_plant_params()`) - written as JSON via `write()`, always the whole
accumulated sample list rewritten to the same file, never appended.
`tasks/server_log.py`'s `ServerLogTask` records continuously for the whole
server session, regardless of Sud state - useful for verifying controller
and heater behaviour outside of a scheduled brew. It starts on construction
and is written to `logs/log_<date>T<time>.json` on shutdown.
and is written to `logs/log_<date>T<time>.json` on shutdown, and again
every `log_interval` seconds (`config.json`, default 300) in between so a
hard crash or power loss only loses up to that much data.
`tasks/sud_log.py`'s `SudLogTask` subclasses `ServerLogTask` to reuse the
same sample format, but only records while a Sud run is actually active. A
fresh run starts recording on a genuine `Start` from `IDLE`/`DONE` (a
`Pause`→resume `Start` is a no-op - it's still the same run) and is written
out on `Stop` or natural completion (`DONE`), to
`logs/log_<date>T<time>_<sud-name>.log`.
same sample format and `log_interval` checkpointing, but only records while
a Sud run is actually active. A fresh run starts recording on a genuine
`Start` from `IDLE`/`DONE` (a `Pause`→resume `Start` is a no-op - it's still
the same run) and is written out on `Stop` or natural completion (`DONE`),
to `logs/log_<date>T<time>_<sud-name>.log`.
`server/brewpi.py` also mirrors everything it prints (every component's
`print()`-based status/debug output) to a plain text log,