fix(hub): improve monitor host status bar layout and document psutil setup

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-13 14:10:00 +08:00
parent 1fd0003fc8
commit a89b446d74
5 changed files with 169 additions and 101 deletions
+40 -48
View File
@@ -112,24 +112,35 @@
function renderHostStatusBar(data) {
const bar = document.getElementById("host-status-bar");
if (!bar) return;
const dot = document.getElementById("host-status-dot");
const name = document.getElementById("host-status-name");
const uptime = document.getElementById("host-status-uptime");
const updated = document.getElementById("host-status-updated");
const cpuVal = document.getElementById("host-cpu-val");
const cpuSub = document.getElementById("host-cpu-sub");
const memVal = document.getElementById("host-mem-val");
const memSub = document.getElementById("host-mem-sub");
const diskVal = document.getElementById("host-disk-val");
const diskSub = document.getElementById("host-disk-sub");
const netUp = document.getElementById("host-net-up");
const netDown = document.getElementById("host-net-down");
if (!data || !data.ok) {
bar.classList.remove("hidden");
const dot = document.getElementById("host-status-dot");
const name = document.getElementById("host-status-name");
const uptime = document.getElementById("host-status-uptime");
if (dot) {
dot.className = "host-status-dot bad";
if (dot) dot.className = "host-status-dot bad";
if (name) {
name.textContent = "服务器";
name.title = "";
}
if (name) name.textContent = "服务器";
if (uptime) uptime.textContent = (data && data.msg) || "状态不可用";
const cpuVal = document.getElementById("host-cpu-val");
const memVal = document.getElementById("host-mem-val");
const diskVal = document.getElementById("host-disk-val");
const netVal = document.getElementById("host-net-val");
if (updated) updated.textContent = "";
if (cpuVal) cpuVal.textContent = "—";
if (cpuSub) cpuSub.textContent = "";
if (memVal) memVal.textContent = "—";
if (memSub) memSub.textContent = "";
if (diskVal) diskVal.textContent = "—";
if (netVal) netVal.textContent = "";
if (diskSub) diskSub.textContent = "";
if (netUp) netUp.textContent = "↑ —";
if (netDown) netDown.textContent = "↓ —";
return;
}
bar.classList.remove("hidden");
@@ -145,50 +156,31 @@
let overall = "ok";
if (levels.includes("bad")) overall = "bad";
else if (levels.includes("warn")) overall = "warn";
const dot = document.getElementById("host-status-dot");
const name = document.getElementById("host-status-name");
const uptime = document.getElementById("host-status-uptime");
if (dot) dot.className = "host-status-dot " + overall;
if (name) name.textContent = data.hostname || "服务器";
if (uptime) {
uptime.textContent =
"运行 " +
fmtHostUptime(data.uptime_sec) +
(data.updated_at ? " · " + data.updated_at : "");
const hostname = data.hostname || "服务器";
if (name) {
name.textContent = hostname;
name.title = hostname;
}
if (uptime) uptime.textContent = "运行 " + fmtHostUptime(data.uptime_sec);
if (updated) updated.textContent = data.updated_at ? "更新 " + data.updated_at : "";
setHostMetricBar(document.getElementById("host-cpu-fill"), cpu.percent);
setHostMetricBar(document.getElementById("host-mem-fill"), mem.percent);
setHostMetricBar(document.getElementById("host-disk-fill"), disk.percent);
const cpuVal = document.getElementById("host-cpu-val");
const memVal = document.getElementById("host-mem-val");
const diskVal = document.getElementById("host-disk-val");
const netVal = document.getElementById("host-net-val");
if (cpuVal) {
cpuVal.textContent =
(cpu.percent != null ? cpu.percent + "%" : "—") +
(cpu.count ? " · " + cpu.count + "核" : "");
if (cpuVal) cpuVal.textContent = cpu.percent != null ? cpu.percent + "%" : "—";
if (cpuSub) cpuSub.textContent = cpu.count ? cpu.count + " 核" : "";
if (memVal) memVal.textContent = mem.percent != null ? mem.percent + "%" : "—";
if (memSub) {
memSub.textContent =
fmtHostBytes(mem.used_bytes) + " / " + fmtHostBytes(mem.total_bytes);
}
if (memVal) {
memVal.textContent =
(mem.percent != null ? mem.percent + "%" : "—") +
" · " +
fmtHostBytes(mem.used_bytes) +
"/" +
fmtHostBytes(mem.total_bytes);
}
if (diskVal) {
diskVal.textContent =
(disk.percent != null ? disk.percent + "%" : "—") +
" · " +
fmtHostBytes(disk.used_bytes) +
"/" +
fmtHostBytes(disk.total_bytes);
}
if (netVal) {
const up = fmtHostBytes(net.sent_rate_bps) + "/s";
const down = fmtHostBytes(net.recv_rate_bps) + "/s";
netVal.textContent = "↑" + up + " ↓" + down;
if (diskVal) diskVal.textContent = disk.percent != null ? disk.percent + "%" : "—";
if (diskSub) {
diskSub.textContent =
fmtHostBytes(disk.used_bytes) + " / " + fmtHostBytes(disk.total_bytes);
}
if (netUp) netUp.textContent = "↑ " + fmtHostBytes(net.sent_rate_bps) + "/s";
if (netDown) netDown.textContent = "↓ " + fmtHostBytes(net.recv_rate_bps) + "/s";
}
async function fetchHostStatus() {