README: add Quick run block, architecture diagram, dry-run gallery and demo GIF; add terminal renderer script
This commit is contained in:
@@ -5,6 +5,61 @@
|
||||
|
||||
A robust system health monitoring daemon that tracks hardware status and automatically creates tickets for detected issues.
|
||||
|
||||

|
||||
|
||||
## ⚡ Quick run
|
||||
|
||||
Copy and paste on any Proxmox node (as root). No clone needed.
|
||||
|
||||
```bash
|
||||
# Test it: prints the health summary and the tickets it WOULD create (nothing is sent)
|
||||
python3 -c "import urllib.request; exec(urllib.request.urlopen('https://code.lotusguild.org/LotusGuild/hwmonDaemon/raw/branch/main/hwmonDaemon.py').read().decode('utf-8'))" --dry-run
|
||||
|
||||
# Run for real (creates tickets)
|
||||
python3 -c "import urllib.request; exec(urllib.request.urlopen('https://code.lotusguild.org/LotusGuild/hwmonDaemon/raw/branch/main/hwmonDaemon.py').read().decode('utf-8'))"
|
||||
|
||||
# Install the systemd timer (hourly check)
|
||||
curl -o /etc/systemd/system/hwmon.service https://code.lotusguild.org/LotusGuild/hwmonDaemon/raw/branch/main/hwmon.service && curl -o /etc/systemd/system/hwmon.timer https://code.lotusguild.org/LotusGuild/hwmonDaemon/raw/branch/main/hwmon.timer && systemctl daemon-reload && systemctl enable --now hwmon.timer
|
||||
```
|
||||
|
||||
## Why this exists
|
||||
|
||||
A six-node Proxmox/Ceph cluster fails in small, boring ways: a drive starts reallocating sectors, a node runs hot, a pool fills up, Ceph reports slow operations. Nobody watches a dashboard all day, and a naive alert that fires every hour buries the one that matters. hwmonDaemon runs on every node, checks the hardware, and files **one ticket per real problem** in [Tinker Tickets](https://code.lotusguild.org/LotusGuild/tinker_tickets), with the diagnosis already written up.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph node["each Proxmox node (systemd timer)"]
|
||||
smart["SMART + drive usage"] --> detect
|
||||
sys["memory / CPU load / ECC"] --> detect
|
||||
net["management + Ceph network"] --> detect
|
||||
ceph["Ceph health + OSDs"] --> detect
|
||||
lxc["LXC storage"] --> detect
|
||||
detect{{"Detect + filter<br/>sustained load, standing flags"}}
|
||||
end
|
||||
detect -->|"dedup key: category + host + device"| api["Tinker Tickets API"]
|
||||
api -->|"open ticket exists"| upd["update it"]
|
||||
api -->|"closed, problem recurs"| reopen["reopen it"]
|
||||
api -->|"new problem"| new["create ticket"]
|
||||
```
|
||||
|
||||
Design choices worth calling out:
|
||||
- **Dedup by hash** of category + hostname + device, so a repeating alert updates the existing ticket and a recurrence reopens a closed one.
|
||||
- **Sustained, not spiky:** CPU tickets are gated on the 15-minute load average per core, not a transient spike.
|
||||
- **Knows the cluster:** a standing Ceph `noout` flag (set on purpose for a node without a UPS) is not ticketed.
|
||||
- **Dry-run first:** `--dry-run` prints exactly what would be filed, which is how the screenshots below were produced (on a live node, with nothing sent).
|
||||
|
||||
## Gallery
|
||||
|
||||
Output from a live node (`micro1`) in dry-run mode:
|
||||
|
||||

|
||||
|
||||
An issue was detected (Ceph reporting slow BlueStore operations), so the daemon renders the ticket it would create, including an executive summary and the cluster status:
|
||||
|
||||

|
||||
|
||||
<sub>Rendered from real command output with `scripts/render_terminal.py`.</sub>
|
||||
|
||||
## Features
|
||||
|
||||
- Comprehensive system health monitoring:
|
||||
|
||||
Reference in New Issue
Block a user