计算移动到后端进行
This commit is contained in:
@@ -706,12 +706,12 @@
|
|||||||
valB = b.cpuPercent ?? 0;
|
valB = b.cpuPercent ?? 0;
|
||||||
break;
|
break;
|
||||||
case 'mem':
|
case 'mem':
|
||||||
valA = a.memTotal > 0 ? (a.memUsed / a.memTotal) : 0;
|
valA = a.memPercent ?? 0;
|
||||||
valB = b.memTotal > 0 ? (b.memUsed / b.memTotal) : 0;
|
valB = b.memPercent ?? 0;
|
||||||
break;
|
break;
|
||||||
case 'disk':
|
case 'disk':
|
||||||
valA = a.diskTotal > 0 ? (a.diskUsed / a.diskTotal) : 0;
|
valA = a.diskPercent ?? 0;
|
||||||
valB = b.diskTotal > 0 ? (b.diskUsed / b.diskTotal) : 0;
|
valB = b.diskPercent ?? 0;
|
||||||
break;
|
break;
|
||||||
case 'netRx':
|
case 'netRx':
|
||||||
valA = a.netRx ?? 0;
|
valA = a.netRx ?? 0;
|
||||||
@@ -853,8 +853,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
dom.serverTableBody.innerHTML = servers.map(server => {
|
dom.serverTableBody.innerHTML = servers.map(server => {
|
||||||
const memPct = server.memTotal > 0 ? (server.memUsed / server.memTotal * 100) : 0;
|
const memPct = server.memPercent || 0;
|
||||||
const diskPct = server.diskTotal > 0 ? (server.diskUsed / server.diskTotal * 100) : 0;
|
const diskPct = server.diskPercent || 0;
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<tr data-instance="${escapeHtml(server.instance)}" data-job="${escapeHtml(server.job)}" data-source="${escapeHtml(server.source)}" style="cursor: pointer;">
|
<tr data-instance="${escapeHtml(server.instance)}" data-job="${escapeHtml(server.job)}" data-source="${escapeHtml(server.source)}" style="cursor: pointer;">
|
||||||
@@ -943,9 +943,8 @@
|
|||||||
dom.detailUptime.textContent = `${days}天 ${hours}小时 ${mins}分`;
|
dom.detailUptime.textContent = `${days}天 ${hours}小时 ${mins}分`;
|
||||||
|
|
||||||
// Disk Total
|
// Disk Total
|
||||||
const totalDiskSize = (data.partitions || []).reduce((sum, p) => sum + (p.size || 0), 0);
|
|
||||||
if (dom.detailDiskTotal) {
|
if (dom.detailDiskTotal) {
|
||||||
dom.detailDiskTotal.textContent = formatBytes(totalDiskSize);
|
dom.detailDiskTotal.textContent = formatBytes(data.totalDiskSize || 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define metrics to show
|
// Define metrics to show
|
||||||
@@ -1118,15 +1117,8 @@
|
|||||||
if (!res.ok) throw new Error('Query failed');
|
if (!res.ok) throw new Error('Query failed');
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
|
|
||||||
if (metricKey === 'cpuBusy' && data.series) {
|
if (metricKey === 'networkTrend' && data.stats) {
|
||||||
// Simplify: ONLY show total busy CPU usage (everything except idle)
|
const stats = data.stats;
|
||||||
// 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);
|
|
||||||
const summaryDiv = document.getElementById(`summary-${metricKey}`);
|
const summaryDiv = document.getElementById(`summary-${metricKey}`);
|
||||||
if (summaryDiv) {
|
if (summaryDiv) {
|
||||||
summaryDiv.style.display = 'flex';
|
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) {
|
window.loadCustomMetricHistory = async function (metricKey, event) {
|
||||||
if (event) event.stopPropagation();
|
if (event) event.stopPropagation();
|
||||||
|
|||||||
@@ -238,7 +238,9 @@ async function getOverviewMetrics(url, sourceName) {
|
|||||||
diskUsed: 0,
|
diskUsed: 0,
|
||||||
netRx: 0,
|
netRx: 0,
|
||||||
netTx: 0,
|
netTx: 0,
|
||||||
up: false
|
up: false,
|
||||||
|
memPercent: 0,
|
||||||
|
diskPercent: 0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const inst = instances.get(token);
|
const inst = instances.get(token);
|
||||||
@@ -308,6 +310,9 @@ async function getOverviewMetrics(url, sourceName) {
|
|||||||
if (!inst.up && (inst.cpuPercent > 0 || inst.memTotal > 0)) {
|
if (!inst.up && (inst.cpuPercent > 0 || inst.memTotal > 0)) {
|
||||||
inst.up = true;
|
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());
|
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
|
percent: p.size > 0 ? ((p.size - p.free) / p.size * 100) : 0
|
||||||
})).sort((a, b) => a.mountpoint.localeCompare(b.mountpoint));
|
})).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_size;
|
||||||
delete results.partitions_free;
|
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])));
|
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
|
// 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 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);
|
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];
|
const expr = metricMap[metric];
|
||||||
|
|||||||
Reference in New Issue
Block a user