fix: report actual memory without cache
This commit is contained in:
@@ -451,7 +451,7 @@ function NodeMonitorPage({ nodes, systemStatuses, onRaw, refresh }: AnyRecord) {
|
||||
h("div", { className: "docker-meta" },
|
||||
h("span", null, `${cpu.cores || 0} CPU cores`),
|
||||
h("span", null, `load ${asNumber(cpu.load1).toFixed(2)} / ${asNumber(cpu.load5).toFixed(2)} / ${asNumber(cpu.load15).toFixed(2)}`),
|
||||
h("span", null, `memory ${fmtBytes(memory.usedBytes)} / ${fmtBytes(memory.totalBytes)}`),
|
||||
h("span", null, `memory actual ${fmtBytes(memory.usedBytes)} / ${fmtBytes(memory.totalBytes)}`),
|
||||
h("span", null, `disk ${fmtBytes(disk.usedBytes)} / ${fmtBytes(disk.totalBytes)}`),
|
||||
),
|
||||
),
|
||||
@@ -459,12 +459,12 @@ function NodeMonitorPage({ nodes, systemStatuses, onRaw, refresh }: AnyRecord) {
|
||||
),
|
||||
h("div", { className: "monitor-chart-grid" },
|
||||
h(MetricChart, { title: "CPU", metricKey: "cpuPercent", current: cpu.percent, points, detail: `${cpu.cores || 0} cores / load ${asNumber(cpu.load1).toFixed(2)}`, tone: "cpu", testId: "metric-chart-cpu" }),
|
||||
h(MetricChart, { title: "Memory", metricKey: "memoryPercent", current: memory.percent, points, detail: `${fmtBytes(memory.usedBytes)} used / ${fmtBytes(memory.availableBytes)} free`, tone: "memory", testId: "metric-chart-memory" }),
|
||||
h(MetricChart, { title: "Memory", metricKey: "memoryPercent", current: memory.percent, points, detail: `${fmtBytes(memory.usedBytes)} actual / ${fmtBytes(memory.cacheBytes)} cache excluded`, tone: "memory", testId: "metric-chart-memory" }),
|
||||
h(MetricChart, { title: "Disk", metricKey: "diskPercent", current: disk.percent, points, detail: `${disk.path || "/"} mounted ${disk.mount || "--"}`, tone: "disk", testId: "metric-chart-disk" }),
|
||||
),
|
||||
h("div", { className: "monitor-summary-grid" },
|
||||
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(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 }),
|
||||
),
|
||||
@@ -475,7 +475,7 @@ function NodeMonitorPage({ nodes, systemStatuses, onRaw, refresh }: AnyRecord) {
|
||||
h(Panel, { title: "采样说明", eyebrow: "Retention" },
|
||||
h("div", { className: "monitor-note-list" },
|
||||
h("article", null, h("b", null, "CPU"), h("span", null, "从 /proc/stat 计算相邻采样差值,首个采样用 load/cores 近似")),
|
||||
h("article", null, h("b", null, "Memory"), h("span", null, "使用 MemTotal 与 MemAvailable 计算已用比例")),
|
||||
h("article", null, h("b", null, "Memory"), h("span", null, "实际内存 = MemTotal - MemFree - Buffers - Cached - SReclaimable + Shmem,不把 page cache / buffer 计入占用")),
|
||||
h("article", null, h("b", null, "Disk"), h("span", null, "使用 df -PB1 对配置路径采样,默认监控根文件系统")),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -380,16 +380,29 @@ async function collectSystemStatus(): Promise<SystemStatusSnapshot> {
|
||||
errors.push({ source: "proc.stat", error: error instanceof Error ? error.message : String(error) });
|
||||
}
|
||||
|
||||
let memory: Record<string, JsonValue> = { totalBytes: 0, usedBytes: 0, availableBytes: 0, percent: 0 };
|
||||
let memory: Record<string, JsonValue> = { totalBytes: 0, usedBytes: 0, availableBytes: 0, cacheBytes: 0, percent: 0, mode: "actual_without_cache" };
|
||||
try {
|
||||
const mem = readMemInfo();
|
||||
const totalBytes = mem.MemTotal ?? 0;
|
||||
const availableBytes = mem.MemAvailable ?? mem.MemFree ?? 0;
|
||||
const usedBytes = Math.max(0, totalBytes - availableBytes);
|
||||
const freeBytes = mem.MemFree ?? 0;
|
||||
const buffersBytes = mem.Buffers ?? 0;
|
||||
const cachedBytes = mem.Cached ?? 0;
|
||||
const reclaimableBytes = mem.SReclaimable ?? 0;
|
||||
const shmemBytes = mem.Shmem ?? 0;
|
||||
const cacheBytes = Math.max(0, buffersBytes + cachedBytes + reclaimableBytes - shmemBytes);
|
||||
const usedBytes = Math.max(0, totalBytes - freeBytes - cacheBytes);
|
||||
const availableBytes = mem.MemAvailable ?? Math.max(0, freeBytes + cacheBytes);
|
||||
memory = {
|
||||
mode: "actual_without_cache",
|
||||
totalBytes,
|
||||
usedBytes,
|
||||
availableBytes,
|
||||
freeBytes,
|
||||
cacheBytes,
|
||||
buffersBytes,
|
||||
cachedBytes,
|
||||
reclaimableBytes,
|
||||
shmemBytes,
|
||||
percent: totalBytes > 0 ? clampPercent((usedBytes / totalBytes) * 100) : 0,
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user