feat: optimize node monitoring and system info

This commit is contained in:
sagitchu
2026-03-21 18:40:28 +08:00
parent ce2b234843
commit ca3a643ef7
3 changed files with 64 additions and 22 deletions
+3 -1
View File
@@ -609,6 +609,8 @@ export default function NodePage() {
if (!metric || typeof metric !== "object") return node; if (!metric || typeof metric !== "object") return node;
const incomingUptime = metric.uptime ?? 0;
return { return {
...node, ...node,
connectionStatus: "online", connectionStatus: "online",
@@ -620,7 +622,7 @@ export default function NodePage() {
downloadTraffic: metric.netInBytes ?? metric.bytes_received ?? 0, downloadTraffic: metric.netInBytes ?? metric.bytes_received ?? 0,
uploadSpeed: metric.netOutSpeed ?? metric.net_out_speed ?? 0, uploadSpeed: metric.netOutSpeed ?? metric.net_out_speed ?? 0,
downloadSpeed: metric.netInSpeed ?? metric.net_in_speed ?? 0, downloadSpeed: metric.netInSpeed ?? metric.net_in_speed ?? 0,
uptime: metric.uptime ?? 0, uptime: incomingUptime || node.systemInfo?.uptime || 0,
diskUsage: metric.diskUsage ?? metric.disk_usage, diskUsage: metric.diskUsage ?? metric.disk_usage,
load1: metric.load1, load1: metric.load1,
load5: metric.load5, load5: metric.load5,
+24 -20
View File
@@ -386,27 +386,31 @@ export function MonitorView({ nodeMap, viewMode = "grid" }: MonitorViewProps) {
const metric = raw as Record<string, unknown>; const metric = raw as Record<string, unknown>;
const receivedAt = Date.now(); const receivedAt = Date.now();
const normalized: RealtimeNodeMetric = { const incomingUptime = Number(metric.uptime ?? 0);
receivedAt,
cpuUsage: Number(metric.cpuUsage ?? metric.cpu_usage ?? 0),
memoryUsage: Number(metric.memoryUsage ?? metric.memory_usage ?? 0),
diskUsage: Number(metric.diskUsage ?? metric.disk_usage ?? 0),
netInBytes: Number(metric.netInBytes ?? metric.bytes_received ?? 0),
netOutBytes: Number(metric.netOutBytes ?? metric.bytes_transmitted ?? 0),
netInSpeed: Number(metric.netInSpeed ?? metric.net_in_speed ?? 0),
netOutSpeed: Number(metric.netOutSpeed ?? metric.net_out_speed ?? 0),
load1: Number(metric.load1 ?? 0),
load5: Number(metric.load5 ?? 0),
load15: Number(metric.load15 ?? 0),
tcpConns: Number(metric.tcpConns ?? metric.tcp_conns ?? 0),
udpConns: Number(metric.udpConns ?? metric.udp_conns ?? 0),
uptime: Number(metric.uptime ?? 0),
};
setRealtimeNodeMetrics((prev) => ({ setRealtimeNodeMetrics((prev) => {
...prev, const normalized: RealtimeNodeMetric = {
[nodeId]: normalized, receivedAt,
})); cpuUsage: Number(metric.cpuUsage ?? metric.cpu_usage ?? 0),
memoryUsage: Number(metric.memoryUsage ?? metric.memory_usage ?? 0),
diskUsage: Number(metric.diskUsage ?? metric.disk_usage ?? 0),
netInBytes: Number(metric.netInBytes ?? metric.bytes_received ?? 0),
netOutBytes: Number(metric.netOutBytes ?? metric.bytes_transmitted ?? 0),
netInSpeed: Number(metric.netInSpeed ?? metric.net_in_speed ?? 0),
netOutSpeed: Number(metric.netOutSpeed ?? metric.net_out_speed ?? 0),
load1: Number(metric.load1 ?? 0),
load5: Number(metric.load5 ?? 0),
load15: Number(metric.load15 ?? 0),
tcpConns: Number(metric.tcpConns ?? metric.tcp_conns ?? 0),
udpConns: Number(metric.udpConns ?? metric.udp_conns ?? 0),
uptime: incomingUptime || prev[nodeId]?.uptime || 0,
};
return {
...prev,
[nodeId]: normalized,
};
});
setRealtimeNodeStatus((prev) => ({ setRealtimeNodeStatus((prev) => ({
...prev, ...prev,
[nodeId]: "online", [nodeId]: "online",
+37 -1
View File
@@ -48,13 +48,49 @@ const parseRawSystemInfo = (messageData: unknown): RawSystemInfo | null => {
return null; return null;
}; };
/**
* Heuristic to verify the parsed object actually contains system-info fields.
* Prevents non-metric messages (command responses, etc.) from being mistakenly
* treated as system info, which would reset all values to 0 and cause UI flicker.
*/
const SYSTEM_INFO_KEYS = [
"uptime",
"cpu_usage",
"memory_usage",
"disk_usage",
"bytes_received",
"bytes_transmitted",
"net_in_speed",
"net_out_speed",
"tcp_conns",
"udp_conns",
"load1",
"load5",
"load15",
] as const;
const looksLikeSystemInfo = (raw: RawSystemInfo): boolean => {
let matched = 0;
for (const key of SYSTEM_INFO_KEYS) {
if (key in raw && raw[key] !== undefined) {
matched++;
if (matched >= 3) {
return true;
}
}
}
return false;
};
export const buildNodeSystemInfo = ( export const buildNodeSystemInfo = (
messageData: unknown, messageData: unknown,
previous: NodeSystemInfo | null | undefined, previous: NodeSystemInfo | null | undefined,
): NodeSystemInfo | null => { ): NodeSystemInfo | null => {
const raw = parseRawSystemInfo(messageData); const raw = parseRawSystemInfo(messageData);
if (!raw) { if (!raw || !looksLikeSystemInfo(raw)) {
return null; return null;
} }