diff --git a/README.md b/README.md index f1233c2..b5529ea 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ Pushes a JSON object every 2 seconds with real system metrics from `psutil`: - `cpu_pct`, `mem_pct`, `mem_used_mb`, `disk_pct` - `cpu_temp` (reads `/sys/class/thermal/` as fallback) - `uptime_hrs`, `net_rx_kbps`, `net_tx_kbps` (values are in kB/s despite the field names) -- `services` — live Docker container statuses via `docker ps -a`, with a ternary status model (`running`, `warning`, `stopped`). Monitored containers: gitea, samba, pihole, qbittorrent, frpc (ny), pinepods, frpc (ssh), jellyfin. +- `services` — live Docker container statuses via `docker ps -a`, with a ternary status model (`running`, `warning`, `stopped`). Monitored containers: gitea, samba, pihole, qbittorrent, frpc (ny), pinepods, frpc (ssh), jellyfin, kc-start2, kc-monitor. A configured container Docker doesn't report at all (deleted, or a typo in `SERVICES_ALIASES`) is reported as `stopped` and logged once to stdout. - `local_time` fields for RTC sync (`y`, `mo`, `d`, `h`, `m`, `s`) ### contents_server.py -- port 8766 diff --git a/stats_server.py b/stats_server.py index 1030244..8d14081 100644 --- a/stats_server.py +++ b/stats_server.py @@ -71,8 +71,13 @@ SERVICES_ALIASES = { "frpc-ssh": "frpc (ssh)", "jellyfin": "jellyfin", "kancolle-start2-server": "kc-start2", - "kancolle": "kc-monitor", + "kancolle-kcmonitor": "kc-monitor", } + +# Configured names Docker didn't report, so a typo doesn't reprint every 2s +_missing_containers: set[str] = set() + + def _get_docker_services() -> list[dict]: """Query Docker for real container statuses with ternary status model.""" try: @@ -86,7 +91,10 @@ def _get_docker_services() -> list[dict]: if result.returncode != 0: return [] + global _missing_containers + services = [] + seen = set() for line in result.stdout.strip().splitlines(): parts = line.split("\t", 1) if len(parts) != 2: @@ -102,6 +110,20 @@ def _get_docker_services() -> list[dict]: else: status = "stopped" services.append({"name": SERVICES_ALIASES[name], "status": status}) + seen.add(name) + + # A configured name Docker never reported is either a typo or a deleted + # container — show it as stopped instead of dropping it off the dashboard + missing = set(SERVICES_ALIASES) - seen + for name in sorted(missing): + services.append({"name": SERVICES_ALIASES[name], "status": "stopped"}) + + if missing != _missing_containers: + for name in sorted(missing - _missing_containers): + print(f"No container named {name!r} — reporting as stopped") + for name in sorted(_missing_containers - missing): + print(f"Container {name!r} is back") + _missing_containers = missing # Sort: warnings first, then stopped, then running (problems float to top) order = {"warning": 0, "stopped": 1, "running": 2}