Some checks failed
Upstream Sync / Sync latest commits from upstream repo (push) Has been cancelled
130 lines
3.9 KiB
Python
130 lines
3.9 KiB
Python
"""
|
|
系统与网卡指标(供仪表盘轮询)。下行/上行为全机网卡合计速率(估算)。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import time
|
|
from typing import Any, Optional
|
|
|
|
import psutil
|
|
|
|
_last_net_time: float = 0.0
|
|
_last_net: Optional[dict[str, tuple[int, int]]] = None # name -> (sent, recv)
|
|
|
|
|
|
def _net_rates_mbps() -> tuple[Optional[float], Optional[float], dict[str, Any]]:
|
|
"""返回 (上行 Mbps, 下行 Mbps, 原始片段)。"""
|
|
global _last_net_time, _last_net
|
|
now = time.monotonic()
|
|
per = psutil.net_io_counters(pernic=True)
|
|
cur: dict[str, tuple[int, int]] = {k: (v.bytes_sent, v.bytes_recv) for k, v in per.items()}
|
|
detail: dict[str, Any] = {}
|
|
up_mbps = down_mbps = None
|
|
if _last_net is not None and _last_net_time > 0:
|
|
dt = now - _last_net_time
|
|
if dt > 0.05:
|
|
ds = dr = 0
|
|
for name, (sent, recv) in cur.items():
|
|
if name in _last_net:
|
|
ps0, pr0 = _last_net[name]
|
|
ds += max(0, sent - ps0)
|
|
dr += max(0, recv - pr0)
|
|
up_mbps = round((ds * 8) / dt / 1_000_000, 3)
|
|
down_mbps = round((dr * 8) / dt / 1_000_000, 3)
|
|
detail["delta_seconds"] = round(dt, 3)
|
|
_last_net = cur
|
|
_last_net_time = now
|
|
for name, (sent, recv) in cur.items():
|
|
detail.setdefault("interfaces", {})[name] = {
|
|
"bytes_sent": sent,
|
|
"bytes_recv": recv,
|
|
}
|
|
return up_mbps, down_mbps, detail
|
|
|
|
|
|
def snapshot() -> dict[str, Any]:
|
|
try:
|
|
psutil.cpu_percent(interval=None)
|
|
cpu = psutil.cpu_percent(interval=0.15)
|
|
except Exception:
|
|
cpu = None
|
|
try:
|
|
vm = psutil.virtual_memory()
|
|
mem = {
|
|
"percent": vm.percent,
|
|
"used": vm.used,
|
|
"total": vm.total,
|
|
"available": vm.available,
|
|
}
|
|
except Exception:
|
|
mem = {}
|
|
try:
|
|
sm = psutil.swap_memory()
|
|
swap = {"percent": sm.percent, "used": sm.used, "total": sm.total}
|
|
except Exception:
|
|
swap = {}
|
|
|
|
disks = []
|
|
try:
|
|
for part in psutil.disk_partitions(all=False):
|
|
try:
|
|
usage = psutil.disk_usage(part.mountpoint)
|
|
disks.append(
|
|
{
|
|
"device": part.device,
|
|
"mountpoint": part.mountpoint,
|
|
"fstype": part.fstype,
|
|
"percent": usage.percent,
|
|
"free": usage.free,
|
|
"total": usage.total,
|
|
}
|
|
)
|
|
except (PermissionError, OSError):
|
|
continue
|
|
except Exception:
|
|
pass
|
|
|
|
up_mbps, down_mbps, net_detail = _net_rates_mbps()
|
|
|
|
boot = None
|
|
try:
|
|
boot = int(psutil.boot_time())
|
|
except Exception:
|
|
pass
|
|
|
|
ffmpeg_procs = []
|
|
try:
|
|
for p in psutil.process_iter(["pid", "name", "memory_info"]):
|
|
try:
|
|
name = (p.info.get("name") or "").lower()
|
|
if "ffmpeg" not in name:
|
|
continue
|
|
mi = p.info.get("memory_info")
|
|
ffmpeg_procs.append(
|
|
{
|
|
"pid": p.info["pid"],
|
|
"name": p.info.get("name"),
|
|
"rss": mi.rss if mi else 0,
|
|
}
|
|
)
|
|
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
continue
|
|
except Exception:
|
|
pass
|
|
|
|
return {
|
|
"ts": time.time(),
|
|
"cpu_percent": cpu,
|
|
"cpu_count_logical": psutil.cpu_count(logical=True),
|
|
"memory": mem,
|
|
"swap": swap,
|
|
"disks": disks,
|
|
"network": {
|
|
"up_mbps": up_mbps,
|
|
"down_mbps": down_mbps,
|
|
"detail": net_detail,
|
|
},
|
|
"boot_time_unix": boot,
|
|
"ffmpeg_processes": ffmpeg_procs[:24],
|
|
}
|