fix: restore node resource status sync
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -784,11 +784,50 @@ function HeartbeatPage({ nodes }: AnyRecord) {
|
||||
);
|
||||
}
|
||||
|
||||
function metricPointFromCurrent(current: AnyRecord): AnyRecord {
|
||||
const cpu = current?.cpu || {};
|
||||
const memory = current?.memory || {};
|
||||
const disk = current?.disk || {};
|
||||
return {
|
||||
at: current?.collectedAt,
|
||||
cpuPercent: asNumber(cpu.percent),
|
||||
memoryPercent: asNumber(memory.percent),
|
||||
diskPercent: asNumber(disk.percent),
|
||||
memoryUsedBytes: asNumber(memory.usedBytes),
|
||||
memoryTotalBytes: asNumber(memory.totalBytes),
|
||||
diskUsedBytes: asNumber(disk.usedBytes),
|
||||
diskTotalBytes: asNumber(disk.totalBytes),
|
||||
load1: asNumber(cpu.load1),
|
||||
};
|
||||
}
|
||||
|
||||
function synchronizedMetricPoints(history: any[], current: AnyRecord | null): AnyRecord[] {
|
||||
if (!current) return [];
|
||||
const currentPoint = metricPointFromCurrent(current);
|
||||
const currentAt = timeMs(currentPoint.at);
|
||||
const points = (Array.isArray(history) ? history : [])
|
||||
.filter((point) => point && typeof point === "object")
|
||||
.filter((point) => currentAt === null || timeMs(point.at) !== currentAt);
|
||||
points.push(currentPoint);
|
||||
return points
|
||||
.sort((left, right) => (timeMs(left.at) ?? 0) - (timeMs(right.at) ?? 0))
|
||||
.slice(-60);
|
||||
}
|
||||
|
||||
function NodeMonitorPage({ nodes, systemStatuses, tasks, onRaw, refresh }: AnyRecord) {
|
||||
const [selectedProvider, setSelectedProvider] = useState("");
|
||||
const merged = useMemo(() => nodes.map((node: any) => {
|
||||
const status = systemStatuses.find((item: any) => item.providerId === node.providerId);
|
||||
return { ...node, systemCurrent: status?.current || null, systemHistory: status?.history || [], systemUpdatedAt: status?.updatedAt || null };
|
||||
return {
|
||||
...node,
|
||||
systemCurrent: status?.current || null,
|
||||
systemLastKnown: status?.lastKnown || null,
|
||||
systemCurrentCollectedAt: status?.currentCollectedAt || null,
|
||||
systemStale: Boolean(status?.stale),
|
||||
systemStaleSeconds: status?.staleSeconds ?? null,
|
||||
systemHistory: status?.history || [],
|
||||
systemUpdatedAt: status?.updatedAt || null,
|
||||
};
|
||||
}), [nodes, systemStatuses]);
|
||||
const active = merged.find((node: any) => node.providerId === selectedProvider) || merged[0] || null;
|
||||
useEffect(() => {
|
||||
@@ -802,12 +841,10 @@ function NodeMonitorPage({ nodes, systemStatuses, tasks, onRaw, refresh }: AnyRe
|
||||
const cpu = current?.cpu || {};
|
||||
const memory = current?.memory || {};
|
||||
const disk = current?.disk || {};
|
||||
const points = history.length > 0 ? history : current ? [{
|
||||
at: current.collectedAt,
|
||||
cpuPercent: asNumber(cpu.percent),
|
||||
memoryPercent: asNumber(memory.percent),
|
||||
diskPercent: asNumber(disk.percent),
|
||||
}] : [];
|
||||
const points = synchronizedMetricPoints(history, current);
|
||||
const staleText = active.systemCurrentCollectedAt
|
||||
? `最后采样 ${fmtDate(active.systemCurrentCollectedAt)},已过期 ${fmtDuration(asNumber(active.systemStaleSeconds))}`
|
||||
: "最后采样时间不可用";
|
||||
|
||||
return h("div", { className: "monitor-page", "data-testid": "node-monitor-page" },
|
||||
h("div", { className: "docker-node-strip" },
|
||||
@@ -820,7 +857,7 @@ function NodeMonitorPage({ nodes, systemStatuses, tasks, onRaw, refresh }: AnyRe
|
||||
h("span", { className: `pulse ${node.status}` }),
|
||||
h("strong", null, node.name),
|
||||
h("code", null, node.providerId),
|
||||
h("span", null, node.systemCurrent ? `CPU ${fmtPercent(node.systemCurrent.cpu?.percent)} / MEM ${fmtPercent(node.systemCurrent.memory?.percent)}` : "等待指标"),
|
||||
h("span", null, node.systemCurrent ? `CPU ${fmtPercent(node.systemCurrent.cpu?.percent)} / MEM ${fmtPercent(node.systemCurrent.memory?.percent)}` : node.systemStale ? "指标过期" : "等待指标"),
|
||||
)),
|
||||
),
|
||||
h("div", { className: "monitor-layout" },
|
||||
@@ -828,9 +865,9 @@ function NodeMonitorPage({ nodes, systemStatuses, tasks, onRaw, refresh }: AnyRe
|
||||
title: "任务管理器视图",
|
||||
eyebrow: active.name,
|
||||
className: "monitor-main-panel",
|
||||
actions: current ? h(RawButton, { title: `System ${active.providerId}`, data: { current, history }, onOpen: onRaw }) : null,
|
||||
actions: current || active.systemStale ? h(RawButton, { title: `System ${active.providerId}`, data: { current, lastKnown: active.systemLastKnown, currentCollectedAt: active.systemCurrentCollectedAt, stale: active.systemStale, staleSeconds: active.systemStaleSeconds, history }, onOpen: onRaw }) : null,
|
||||
},
|
||||
!current ? h(EmptyState, { title: "系统指标未上报", text: "provider-gateway 会周期性采集 /proc 与 df,并保存历史曲线" }) :
|
||||
!current ? h(EmptyState, { title: active.systemStale ? "系统指标已过期" : "系统指标未上报", text: active.systemStale ? `${staleText};等待 provider-gateway 恢复 system.status 上报` : "provider-gateway 会周期性采集 /proc 与 df,并保存历史曲线" }) :
|
||||
h("div", null,
|
||||
h("div", { className: "monitor-hero" },
|
||||
h("div", null,
|
||||
@@ -854,7 +891,7 @@ function NodeMonitorPage({ nodes, systemStatuses, tasks, onRaw, refresh }: AnyRe
|
||||
h(MetricCard, { label: "CPU 当前", value: fmtPercent(cpu.percent), hint: `history ${points.length} samples`, tone: "ok" }),
|
||||
h(MetricCard, { label: "实际内存", value: fmtBytes(memory.usedBytes), hint: `${fmtPercent(memory.percent)} 不含缓存` }),
|
||||
h(MetricCard, { label: "硬盘已用", value: fmtBytes(disk.usedBytes), hint: fmtPercent(disk.percent) }),
|
||||
h(MetricCard, { label: "更新时间", value: fmtDate(active.systemUpdatedAt || current.collectedAt), hint: active.providerId }),
|
||||
h(MetricCard, { label: "更新时间", value: fmtDate(current.collectedAt || active.systemUpdatedAt), hint: active.providerId }),
|
||||
),
|
||||
h(ProcessResourceTable, { current, onRaw }),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user