From 28432c9c238a8cd1563a0798f258fe3835cfcc8d Mon Sep 17 00:00:00 2001 From: CN-JS-HuiBai Date: Sun, 5 Apr 2026 22:53:23 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A1=E7=AE=97=E7=A7=BB=E5=8A=A8=E5=88=B0?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=E8=BF=9B=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/js/app.js | 58 ++++++------------------------------ server/prometheus-service.js | 41 +++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 52 deletions(-) diff --git a/public/js/app.js b/public/js/app.js index 8542f87..991dcf9 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -706,12 +706,12 @@ valB = b.cpuPercent ?? 0; break; case 'mem': - valA = a.memTotal > 0 ? (a.memUsed / a.memTotal) : 0; - valB = b.memTotal > 0 ? (b.memUsed / b.memTotal) : 0; + valA = a.memPercent ?? 0; + valB = b.memPercent ?? 0; break; case 'disk': - valA = a.diskTotal > 0 ? (a.diskUsed / a.diskTotal) : 0; - valB = b.diskTotal > 0 ? (b.diskUsed / b.diskTotal) : 0; + valA = a.diskPercent ?? 0; + valB = b.diskPercent ?? 0; break; case 'netRx': valA = a.netRx ?? 0; @@ -853,8 +853,8 @@ } dom.serverTableBody.innerHTML = servers.map(server => { - const memPct = server.memTotal > 0 ? (server.memUsed / server.memTotal * 100) : 0; - const diskPct = server.diskTotal > 0 ? (server.diskUsed / server.diskTotal * 100) : 0; + const memPct = server.memPercent || 0; + const diskPct = server.diskPercent || 0; return ` @@ -943,9 +943,8 @@ dom.detailUptime.textContent = `${days}天 ${hours}小时 ${mins}分`; // Disk Total - const totalDiskSize = (data.partitions || []).reduce((sum, p) => sum + (p.size || 0), 0); if (dom.detailDiskTotal) { - dom.detailDiskTotal.textContent = formatBytes(totalDiskSize); + dom.detailDiskTotal.textContent = formatBytes(data.totalDiskSize || 0); } // Define metrics to show @@ -1118,15 +1117,8 @@ if (!res.ok) throw new Error('Query failed'); const data = await res.json(); - if (metricKey === 'cpuBusy' && data.series) { - // Simplify: ONLY show total busy CPU usage (everything except idle) - // Since it's a percentage, 100 - idle is the total busy percentage - data.values = data.series.idle.map(idleVal => Math.max(0, 100 - idleVal)); - data.series = null; // This tells MetricChart to draw a single line instead of stacked area - } - - if (metricKey === 'networkTrend') { - const stats = calculateHistoryStats(data); + if (metricKey === 'networkTrend' && data.stats) { + const stats = data.stats; const summaryDiv = document.getElementById(`summary-${metricKey}`); if (summaryDiv) { summaryDiv.style.display = 'flex'; @@ -1148,38 +1140,6 @@ } }; - function calculateHistoryStats(data) { - if (!data.timestamps || data.timestamps.length < 2) { - return { rxTotal: 0, txTotal: 0, p95: 0, total: 0 }; - } - - const tx = data.tx || []; - const rx = data.rx || []; - const ts = data.timestamps; - - let rxTotal = 0; - let txTotal = 0; - - for (let i = 0; i < ts.length - 1; i++) { - // Find interval in seconds - const duration = (ts[i+1] - ts[i]) / 1000; - // Bandwidth (B/s) * time (s) = Bytes - rxTotal += (rx[i] || 0) * duration; - txTotal += (tx[i] || 0) * duration; - } - - // P95 calculation for TX (consistent with AreaChart) - const sortedTx = [...tx].sort((a, b) => a - b); - const p95Idx = Math.floor(sortedTx.length * 0.95); - const p95 = sortedTx.length > 0 ? sortedTx[p95Idx] : 0; - - return { - rxTotal, - txTotal, - p95, - total: rxTotal + txTotal - }; - } window.loadCustomMetricHistory = async function (metricKey, event) { if (event) event.stopPropagation(); diff --git a/server/prometheus-service.js b/server/prometheus-service.js index 3ee638b..31b2c47 100644 --- a/server/prometheus-service.js +++ b/server/prometheus-service.js @@ -238,7 +238,9 @@ async function getOverviewMetrics(url, sourceName) { diskUsed: 0, netRx: 0, netTx: 0, - up: false + up: false, + memPercent: 0, + diskPercent: 0 }); } const inst = instances.get(token); @@ -308,6 +310,9 @@ async function getOverviewMetrics(url, sourceName) { if (!inst.up && (inst.cpuPercent > 0 || inst.memTotal > 0)) { inst.up = true; } + // Calculate percentages on backend + inst.memPercent = inst.memTotal > 0 ? (inst.memUsed / inst.memTotal * 100) : 0; + inst.diskPercent = inst.diskTotal > 0 ? (inst.diskUsed / inst.diskTotal * 100) : 0; } const allInstancesList = Array.from(instances.values()); @@ -606,6 +611,9 @@ async function getServerDetails(baseUrl, instance, job) { percent: p.size > 0 ? ((p.size - p.free) / p.size * 100) : 0 })).sort((a, b) => a.mountpoint.localeCompare(b.mountpoint)); + // Calculate total disk size + results.totalDiskSize = results.partitions.reduce((sum, p) => sum + (p.size || 0), 0); + delete results.partitions_size; delete results.partitions_free; @@ -659,7 +667,11 @@ async function getServerHistory(baseUrl, instance, job, metric, range = '1h', st r.values.forEach(v => series[r.name].push(parseFloat(v[1]))); }); - return { timestamps, series }; + // Pre-calculate busy percentage: 100 - idle + const idleValues = series.idle || []; + const busyValues = idleValues.map(idleVal => Math.max(0, 100 - idleVal)); + + return { timestamps, series, values: busyValues }; } // Map metric keys to Prometheus expressions @@ -690,7 +702,30 @@ async function getServerHistory(baseUrl, instance, job, metric, range = '1h', st const tx = txResult.length > 0 ? txResult[0].values.map(v => parseFloat(v[1])) : new Array(timestamps.length).fill(0); const rx = rxResult.length > 0 ? rxResult[0].values.map(v => parseFloat(v[1])) : new Array(timestamps.length).fill(0); - return { timestamps, tx, rx }; + // Calculate statistics on backend + let rxTotal = 0; + let txTotal = 0; + for (let i = 0; i < timestamps.length - 1; i++) { + const duration = (timestamps[i+1] - timestamps[i]) / 1000; + rxTotal += (rx[i] || 0) * duration; + txTotal += (tx[i] || 0) * duration; + } + + const sortedTx = [...tx].sort((a, b) => a - b); + const p95Idx = Math.floor(sortedTx.length * 0.95); + const p95 = sortedTx.length > 0 ? sortedTx[p95Idx] : 0; + + return { + timestamps, + tx, + rx, + stats: { + rxTotal, + txTotal, + p95, + total: rxTotal + txTotal + } + }; } const expr = metricMap[metric];