feat: 横版col-extra — 负载/SWAP/磁盘/温度/流量/进程 6项指标
SystemInfoCollector 新增: - swap: SWAP用量 (psutil + /proc/meminfo fallback) - disk: 磁盘用量 - temperature: CPU温度 (psutil + /sys/class/thermal fallback) Sentinel col-extra 显示: 负载 | SWAP | 磁盘 | 温度 | 累计流量 | 进程RSS Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -64,9 +64,12 @@ class SystemInfoCollector:
|
||||
},
|
||||
"cpu": self._get_cpu(),
|
||||
"memory": self._get_memory(),
|
||||
"swap": self._get_swap(),
|
||||
"disk": self._get_disk(),
|
||||
"process": self._get_process(),
|
||||
"network": self._get_network(),
|
||||
"net_speed": self._get_network_speed()
|
||||
"net_speed": self._get_network_speed(),
|
||||
"temperature": self._get_temperature(),
|
||||
}
|
||||
|
||||
def _get_cpu(self) -> Dict[str, Any]:
|
||||
@@ -107,6 +110,71 @@ class SystemInfoCollector:
|
||||
logger.warning(f"Memory info failed: {e}")
|
||||
return {"total_gb": 0, "used_gb": 0, "percent": 0}
|
||||
|
||||
def _get_swap(self) -> Dict[str, Any]:
|
||||
if self.psutil:
|
||||
try:
|
||||
s = self.psutil.swap_memory()
|
||||
return {"total_gb": round(s.total / 1073741824, 1),
|
||||
"used_gb": round(s.used / 1073741824, 1),
|
||||
"percent": s.percent}
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
with open('/proc/meminfo') as f:
|
||||
mem = {}
|
||||
for line in f:
|
||||
parts = line.split()
|
||||
if len(parts) >= 2:
|
||||
mem[parts[0].rstrip(':')] = int(parts[1]) * 1024
|
||||
t = mem.get('SwapTotal', 0)
|
||||
f_swap = mem.get('SwapFree', mem.get('SwapCached', 0))
|
||||
if t > 0:
|
||||
used = t - f_swap
|
||||
return {"total_gb": round(t / 1073741824, 1),
|
||||
"used_gb": round(used / 1073741824, 1),
|
||||
"percent": round((used / t) * 100, 1)}
|
||||
except Exception:
|
||||
pass
|
||||
return {"total_gb": 0, "used_gb": 0, "percent": 0}
|
||||
|
||||
def _get_disk(self) -> Dict[str, Any]:
|
||||
if self.psutil:
|
||||
try:
|
||||
d = self.psutil.disk_usage('/')
|
||||
return {"total_gb": round(d.total / 1073741824, 1),
|
||||
"used_gb": round(d.used / 1073741824, 1),
|
||||
"percent": d.percent}
|
||||
except Exception:
|
||||
pass
|
||||
return {"total_gb": 0, "used_gb": 0, "percent": 0}
|
||||
|
||||
def _get_temperature(self) -> Dict[str, Any]:
|
||||
if self.psutil:
|
||||
try:
|
||||
temps = self.psutil.sensors_temperatures()
|
||||
if temps:
|
||||
for name, entries in temps.items():
|
||||
for e in entries:
|
||||
if e.current > 0:
|
||||
return {"name": e.label or name, "current": round(e.current, 1)}
|
||||
except Exception:
|
||||
pass
|
||||
# Android fallback: read thermal zone
|
||||
try:
|
||||
for i in range(10):
|
||||
tz = f'/sys/class/thermal/thermal_zone{i}/temp'
|
||||
ttype = f'/sys/class/thermal/thermal_zone{i}/type'
|
||||
if os.path.exists(tz) and os.path.exists(ttype):
|
||||
with open(ttype) as f:
|
||||
name = f.read().strip()
|
||||
if 'cpu' in name.lower() or 'soc' in name.lower():
|
||||
with open(tz) as f:
|
||||
temp = int(f.read().strip()) / 1000.0
|
||||
return {"name": name, "current": round(temp, 1)}
|
||||
except Exception:
|
||||
pass
|
||||
return {"name": "", "current": 0}
|
||||
|
||||
def _get_process(self) -> Dict[str, Any]:
|
||||
"""Current process info (PID + RSS memory)"""
|
||||
pid = os.getpid()
|
||||
|
||||
Reference in New Issue
Block a user