README: add Quick run block, architecture diagram, dry-run gallery and demo GIF; add terminal renderer script
Lint / Python (flake8) (push) Failing after 1m4s
Security / Python Security (bandit) (push) Successful in 58s
Test / Python Tests (pytest) (push) Successful in 2m16s
Lint / Notify on failure (push) Successful in 8s

This commit is contained in:
2026-10-03 01:06:06 -04:00
parent 07cdb0d412
commit 90059313b4
5 changed files with 127 additions and 0 deletions
+55
View File
@@ -5,6 +5,61 @@
A robust system health monitoring daemon that tracks hardware status and automatically creates tickets for detected issues.
![hwmonDaemon dry-run: health summary followed by the ticket it would create](docs/img/demo.gif)
## ⚡ 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:
![Health summary](docs/img/dry-run-summary.png)
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:
![Simulated ticket](docs/img/dry-run-ticket.png)
<sub>Rendered from real command output with `scripts/render_terminal.py`.</sub>
## Features
- Comprehensive system health monitoring: