修复BUG
This commit is contained in:
@@ -30,7 +30,23 @@ class AreaChart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setData(data) {
|
setData(data) {
|
||||||
this.data = data;
|
if (!data || !data.timestamps) return;
|
||||||
|
|
||||||
|
// Downsample if data is too dense (target ~1500 points for performance)
|
||||||
|
const MAX_POINTS = 1500;
|
||||||
|
if (data.timestamps.length > MAX_POINTS) {
|
||||||
|
const skip = Math.ceil(data.timestamps.length / MAX_POINTS);
|
||||||
|
const downsampled = { timestamps: [], rx: [], tx: [] };
|
||||||
|
for (let i = 0; i < data.timestamps.length; i += skip) {
|
||||||
|
downsampled.timestamps.push(data.timestamps[i]);
|
||||||
|
downsampled.rx.push(data.rx[i]);
|
||||||
|
downsampled.tx.push(data.tx[i]);
|
||||||
|
}
|
||||||
|
this.data = downsampled;
|
||||||
|
} else {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
this.animProgress = 0;
|
this.animProgress = 0;
|
||||||
this.animate();
|
this.animate();
|
||||||
}
|
}
|
||||||
@@ -132,16 +148,22 @@ class AreaChart {
|
|||||||
drawArea(ctx, values, getX, getY, chartH, p, fillColorTop, fillColorBottom, strokeColor, len) {
|
drawArea(ctx, values, getX, getY, chartH, p, fillColorTop, fillColorBottom, strokeColor, len) {
|
||||||
if (!values || values.length === 0) return;
|
if (!values || values.length === 0) return;
|
||||||
|
|
||||||
|
const useSimple = len > 500;
|
||||||
|
|
||||||
// Fill
|
// Fill
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(getX(0), getY(values[0] || 0));
|
ctx.moveTo(getX(0), getY(values[0] || 0));
|
||||||
for (let i = 1; i < len; i++) {
|
for (let i = 1; i < len; i++) {
|
||||||
const prevX = getX(i - 1);
|
if (useSimple) {
|
||||||
const currX = getX(i);
|
ctx.lineTo(getX(i), getY(values[i] || 0));
|
||||||
const prevY = getY(values[i - 1] || 0);
|
} else {
|
||||||
const currY = getY(values[i] || 0);
|
const prevX = getX(i - 1);
|
||||||
const midX = (prevX + currX) / 2;
|
const currX = getX(i);
|
||||||
ctx.bezierCurveTo(midX, prevY, midX, currY, currX, currY);
|
const prevY = getY(values[i - 1] || 0);
|
||||||
|
const currY = getY(values[i] || 0);
|
||||||
|
const midX = (prevX + currX) / 2;
|
||||||
|
ctx.bezierCurveTo(midX, prevY, midX, currY, currX, currY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ctx.lineTo(getX(len - 1), p.top + chartH);
|
ctx.lineTo(getX(len - 1), p.top + chartH);
|
||||||
ctx.lineTo(getX(0), p.top + chartH);
|
ctx.lineTo(getX(0), p.top + chartH);
|
||||||
@@ -157,15 +179,20 @@ class AreaChart {
|
|||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(getX(0), getY(values[0] || 0));
|
ctx.moveTo(getX(0), getY(values[0] || 0));
|
||||||
for (let i = 1; i < len; i++) {
|
for (let i = 1; i < len; i++) {
|
||||||
const prevX = getX(i - 1);
|
if (useSimple) {
|
||||||
const currX = getX(i);
|
ctx.lineTo(getX(i), getY(values[i] || 0));
|
||||||
const prevY = getY(values[i - 1] || 0);
|
} else {
|
||||||
const currY = getY(values[i] || 0);
|
const prevX = getX(i - 1);
|
||||||
const midX = (prevX + currX) / 2;
|
const currX = getX(i);
|
||||||
ctx.bezierCurveTo(midX, prevY, midX, currY, currX, currY);
|
const prevY = getY(values[i - 1] || 0);
|
||||||
|
const currY = getY(values[i] || 0);
|
||||||
|
const midX = (prevX + currX) / 2;
|
||||||
|
ctx.bezierCurveTo(midX, prevY, midX, currY, currX, currY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ctx.strokeStyle = strokeColor;
|
ctx.strokeStyle = strokeColor;
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
|
ctx.lineJoin = 'round';
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -659,8 +659,8 @@ checkAndFixDatabase().then(() => {
|
|||||||
initialPreload();
|
initialPreload();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Record traffic every 5 minutes
|
// Record traffic every 5 seconds (17,280 points/day)
|
||||||
setInterval(recordTrafficStats, 5 * 60 * 1000);
|
setInterval(recordTrafficStats, 5 * 1000);
|
||||||
// Initial record after a short delay
|
// Initial record after a short delay
|
||||||
setTimeout(recordTrafficStats, 10000);
|
setTimeout(recordTrafficStats, 10000);
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ async function getOverviewMetrics(url, sourceName) {
|
|||||||
// Total traffic transmitted in last 24h
|
// Total traffic transmitted in last 24h
|
||||||
query(url, 'sum by (instance, job) (increase(node_network_transmit_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[24h]))').catch(() => []),
|
query(url, 'sum by (instance, job) (increase(node_network_transmit_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[24h]))').catch(() => []),
|
||||||
// Up instances (at least one successful scrape in last 5m)
|
// Up instances (at least one successful scrape in last 5m)
|
||||||
query(url, 'max_over_time(up{job=~".*node.*|.*exporter.*"}[5m])').catch(() => [])
|
// We broaden the job filter to catch more variations of node-exporter jobs
|
||||||
|
query(url, 'max_over_time(up{job=~".*node.*|.*exporter.*|.*host.*"}[5m])').catch(() => [])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Build per-instance data map
|
// Build per-instance data map
|
||||||
@@ -252,6 +253,14 @@ async function getOverviewMetrics(url, sourceName) {
|
|||||||
inst.netTx = parseFloat(r.value[1]) || 0;
|
inst.netTx = parseFloat(r.value[1]) || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Final check: If an instance has non-zero CPU or Memory total data but is marked offline,
|
||||||
|
// it means we missed its 'up' metric due to job labels, but it's clearly sending data.
|
||||||
|
for (const inst of instances.values()) {
|
||||||
|
if (!inst.up && (inst.cpuPercent > 0 || inst.memTotal > 0)) {
|
||||||
|
inst.up = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Aggregate
|
// Aggregate
|
||||||
let totalCpuUsed = 0, totalCpuCores = 0;
|
let totalCpuUsed = 0, totalCpuCores = 0;
|
||||||
let totalMemUsed = 0, totalMemTotal = 0;
|
let totalMemUsed = 0, totalMemTotal = 0;
|
||||||
@@ -408,7 +417,7 @@ function mergeCpuHistories(histories) {
|
|||||||
async function getTrafficHistoryRange(url) {
|
async function getTrafficHistoryRange(url) {
|
||||||
const now = Math.floor(Date.now() / 1000);
|
const now = Math.floor(Date.now() / 1000);
|
||||||
const start = now - 86400; // 24h ago
|
const start = now - 86400; // 24h ago
|
||||||
const step = 300; // 5 minutes
|
const step = 5; // 5 seconds (17,280 points for 24h)
|
||||||
|
|
||||||
const queries = [
|
const queries = [
|
||||||
'sum(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*|br-.*"})',
|
'sum(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*|br-.*"})',
|
||||||
|
|||||||
Reference in New Issue
Block a user