July 08, 2026 UTC+8
Hot Rotation
Rewrote run.py as a multi-threaded log orchestration layer: a daemon threading.Timer loop fires every 3600 s (configurable via --rotate-interval N, disable with --no-rotate). threading.RLock guards StreamCatch.write() to serialize concurrent writes from Uvicorn's async worker pool. Rotation critical section (io.open new file descriptor → close old fd) executes under lock; regex analysis and file rename run post-unlock to minimize write-path blocking. Uvicorn.Server.run() remains on the main thread, decoupled from the rotation daemon lifecycle — no process restart required.
July 08, 2026 UTC+8
Suffix Tagging
Post-rotation analysis pipeline: full-content re.search across rotated log for ERROR | WARNING | Exception | Traceback | timeout patterns. Filename suffix convention: _E (errors present), _W (warnings present), _EW (both). WMI GPU sensor noise (recurring failed WMI query) excluded via negative-lookahead regex to prevent false-positive _W tagging on every rotation cycle. Context extraction captures ±1 line around each match for forensic correlation.
July 08, 2026 UTC+8
AI Digest
Synchronous digest generation alongside each rotation: {hex}_ai_digest.log written with structured plaintext metadata — time_range (first→last timestamp), total_lines, error_count, warning_count, status_label (CLEAN / _E / _W / _EW). Deduplicated error contexts with ±1 line window for each unique match. Deduplicated warning inventory. GET /api/admin/logs extended JSON response schema: files[] (recent 20 rotated log filenames), digests[] (recent 20 digest filenames), total_lines (current active log). Five logger.error() callsites in main.py upgraded to exc_info=True for automatic full Python traceback attachment in log stream output.