dashboard/app/collect/disks.py

55 lines
1.7 KiB
Python

from typing import Any
import psutil
from psutil._ntuples import sdiskio
def counters() -> dict[str, sdiskio]:
return psutil.disk_io_counters(perdisk=True) or {}
def rates(prev: dict[str, sdiskio], dt: float) -> dict[str, float]:
cur = counters()
r = 0
w = 0
for name, c in cur.items():
p = prev.get(name)
if p is not None and dt > 0:
r += max(0, int(c.read_bytes) - int(p.read_bytes))
w += max(0, int(c.write_bytes) - int(p.write_bytes))
return {"io_read": r / dt if dt > 0 else 0.0, "io_write": w / dt if dt > 0 else 0.0}
def partitions() -> list[dict[str, Any]]:
groups: dict[str, dict[str, Any]] = {}
order: list[str] = []
for p in psutil.disk_partitions(all=False):
if p.device in groups:
g = groups[p.device]
if p.mountpoint not in g["mounts"]:
g["mounts"].append(p.mountpoint)
continue
try:
u = psutil.disk_usage(p.mountpoint)
except (OSError, PermissionError):
continue
g = {
"device": p.device,
"fstype": p.fstype,
"total": u.total,
"used": u.used,
"free": u.free,
"pct": u.percent,
"mounts": [p.mountpoint],
}
groups[p.device] = g
order.append(p.device)
out = [groups[d] for d in sorted(order)]
for g in out:
g["mounts"] = sorted(g["mounts"])
mounts = g["mounts"]
if len(mounts) > 3:
g["mounts_disp"] = " · ".join(mounts[:3]) + f" +{len(mounts) - 3} more"
else:
g["mounts_disp"] = " · ".join(mounts)
return out