feat(hub): show server CPU memory disk and network status on monitor page
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
"""中控:本机 CPU / 内存 / 磁盘 / 网络快照(监控区服务器状态条)。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import socket
|
||||
import time
|
||||
from typing import Any
|
||||
|
||||
_state: dict[str, Any] = {
|
||||
"primed": False,
|
||||
"net_ts": 0.0,
|
||||
"net_sent": 0,
|
||||
"net_recv": 0,
|
||||
}
|
||||
|
||||
|
||||
def _disk_path() -> str:
|
||||
raw = (os.getenv("HUB_HOST_DISK_PATH") or "").strip()
|
||||
if raw:
|
||||
return raw
|
||||
if os.name == "nt":
|
||||
drive = (os.environ.get("SystemDrive") or "C:").strip()
|
||||
return drive if drive.endswith(("\\", "/")) else drive + "\\"
|
||||
return "/"
|
||||
|
||||
|
||||
def _safe_int(value: Any) -> int:
|
||||
try:
|
||||
return int(value)
|
||||
except (TypeError, ValueError):
|
||||
return 0
|
||||
|
||||
|
||||
def get_host_status() -> dict[str, Any]:
|
||||
try:
|
||||
import psutil
|
||||
except ImportError:
|
||||
return {
|
||||
"ok": False,
|
||||
"msg": "未安装 psutil,请在 manual-trading-hub 环境执行 pip install psutil",
|
||||
}
|
||||
|
||||
now = time.time()
|
||||
if not _state["primed"]:
|
||||
psutil.cpu_percent(interval=None)
|
||||
_state["primed"] = True
|
||||
|
||||
cpu_pct = float(psutil.cpu_percent(interval=None))
|
||||
cpu_count = int(psutil.cpu_count(logical=True) or 0)
|
||||
|
||||
vm = psutil.virtual_memory()
|
||||
disk_path = _disk_path()
|
||||
du = psutil.disk_usage(disk_path)
|
||||
|
||||
net = psutil.net_io_counters()
|
||||
sent_rate = 0.0
|
||||
recv_rate = 0.0
|
||||
if net is not None and _state["net_ts"] > 0:
|
||||
dt = max(0.001, now - float(_state["net_ts"]))
|
||||
sent_rate = max(0.0, (net.bytes_sent - int(_state["net_sent"])) / dt)
|
||||
recv_rate = max(0.0, (net.bytes_recv - int(_state["net_recv"])) / dt)
|
||||
if net is not None:
|
||||
_state["net_ts"] = now
|
||||
_state["net_sent"] = int(net.bytes_sent)
|
||||
_state["net_recv"] = int(net.bytes_recv)
|
||||
|
||||
disk_total = _safe_int(du.total)
|
||||
disk_used = _safe_int(du.used)
|
||||
disk_pct = round(disk_used / disk_total * 100, 1) if disk_total > 0 else 0.0
|
||||
|
||||
boot = float(psutil.boot_time())
|
||||
return {
|
||||
"ok": True,
|
||||
"hostname": socket.gethostname(),
|
||||
"uptime_sec": max(0, int(now - boot)),
|
||||
"cpu": {
|
||||
"percent": round(cpu_pct, 1),
|
||||
"count": cpu_count,
|
||||
},
|
||||
"memory": {
|
||||
"total_bytes": _safe_int(vm.total),
|
||||
"used_bytes": _safe_int(vm.used),
|
||||
"percent": round(float(vm.percent), 1),
|
||||
},
|
||||
"disk": {
|
||||
"path": disk_path,
|
||||
"total_bytes": disk_total,
|
||||
"used_bytes": disk_used,
|
||||
"percent": disk_pct,
|
||||
},
|
||||
"network": {
|
||||
"bytes_sent": _safe_int(net.bytes_sent if net else 0),
|
||||
"bytes_recv": _safe_int(net.bytes_recv if net else 0),
|
||||
"sent_rate_bps": round(sent_rate, 1),
|
||||
"recv_rate_bps": round(recv_rate, 1),
|
||||
},
|
||||
"updated_at": time.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
}
|
||||
Reference in New Issue
Block a user