Add system info
This commit is contained in:
73
app.py
73
app.py
@@ -48,6 +48,68 @@ def docker_stats() -> dict:
|
||||
}
|
||||
return stats
|
||||
|
||||
import re
|
||||
|
||||
def docker_info() -> dict:
|
||||
# docker info --format "{{json .}}" gives us structured host-level info
|
||||
out = sh([DOCKER, "info", "--format", "{{json .}}"])
|
||||
return json.loads(out)
|
||||
|
||||
def docker_system_df() -> dict:
|
||||
# Parse `docker system df` (text). It's stable enough for a dashboard.
|
||||
out = sh([DOCKER, "system", "df"])
|
||||
# Example lines:
|
||||
# Images 175 18 15.15GB 13.93GB (91%)
|
||||
# Containers 27 26 145.1MB 16.57kB (0%)
|
||||
# Local Volumes 47 1 817.7MB 817.7MB (100%)
|
||||
# Build Cache 889 0 423B 423B
|
||||
rows = {}
|
||||
for line in out.splitlines():
|
||||
line = line.strip()
|
||||
if not line or line.startswith("TYPE"):
|
||||
continue
|
||||
parts = re.split(r"\s{2,}", line)
|
||||
if len(parts) >= 5:
|
||||
typ, total, active, size, reclaimable = parts[:5]
|
||||
rows[typ] = {
|
||||
"total": total,
|
||||
"active": active,
|
||||
"size": size,
|
||||
"reclaimable": reclaimable,
|
||||
}
|
||||
return rows
|
||||
|
||||
def system_summary() -> dict:
|
||||
info = docker_info()
|
||||
df = docker_system_df()
|
||||
|
||||
return {
|
||||
"name": info.get("Name", ""),
|
||||
"server_version": info.get("ServerVersion", ""),
|
||||
"operating_system": info.get("OperatingSystem", ""),
|
||||
"os_type": info.get("OSType", ""),
|
||||
"architecture": info.get("Architecture", ""),
|
||||
"kernel_version": info.get("KernelVersion", ""),
|
||||
"cpus": info.get("NCPU", ""),
|
||||
"mem_total": info.get("MemTotal", ""), # bytes
|
||||
"containers": info.get("Containers", ""),
|
||||
"containers_running": info.get("ContainersRunning", ""),
|
||||
"containers_stopped": info.get("ContainersStopped", ""),
|
||||
"images": info.get("Images", ""),
|
||||
"docker_root_dir": info.get("DockerRootDir", ""),
|
||||
"system_df": df,
|
||||
}
|
||||
|
||||
def format_bytes(n: int) -> str:
|
||||
# for mem_total
|
||||
units = ["B", "KB", "MB", "GB", "TB"]
|
||||
f = float(n)
|
||||
for u in units:
|
||||
if f < 1024 or u == units[-1]:
|
||||
return f"{f:.1f}{u}"
|
||||
f /= 1024
|
||||
return f"{n}B"
|
||||
|
||||
def docker_inspect_restart_count(container_name: str) -> int:
|
||||
# RestartCount is useful when stuff is flapping / OOMing
|
||||
try:
|
||||
@@ -126,11 +188,22 @@ def collect():
|
||||
warnings.append(f"{a['app']} RAM high ({a['mem_pct']})")
|
||||
if a["restarts"] >= 3:
|
||||
warnings.append(f"{a['app']} restarting (restarts={a['restarts']})")
|
||||
|
||||
sysinfo = system_summary()
|
||||
|
||||
# format mem bytes nicely
|
||||
try:
|
||||
mem_total_h = format_bytes(int(sysinfo["mem_total"]))
|
||||
except Exception:
|
||||
mem_total_h = ""
|
||||
|
||||
sysinfo["mem_total_h"] = mem_total_h
|
||||
|
||||
return {
|
||||
"generated_at": datetime.utcnow().isoformat() + "Z",
|
||||
"poll_seconds": POLL_SECONDS,
|
||||
"domain": APP_DOMAIN,
|
||||
"system": sysinfo,
|
||||
"apps": apps,
|
||||
"infra": infra,
|
||||
"warnings": warnings,
|
||||
|
||||
Reference in New Issue
Block a user