diff --git a/server/prometheus-service.js b/server/prometheus-service.js index af45f04..41ad658 100644 --- a/server/prometheus-service.js +++ b/server/prometheus-service.js @@ -391,25 +391,23 @@ function calculateTrafficFromHistory(values) { } /** - * Get total traffic for the past 24h by fetching all points and integrating + * Get total traffic for the past 24h using Prometheus increase() for stability and accuracy */ async function get24hTrafficSum(url) { - const now = Math.floor(Date.now() / 1000); - const start = now - 86400; - const step = 60; // 1-minute points for calculation + try { + const [rxResult, txResult] = await Promise.all([ + query(url, 'sum(increase(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[24h]))').catch(() => []), + query(url, 'sum(increase(node_network_transmit_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[24h]))').catch(() => []) + ]); - const [rxResult, txResult] = await Promise.all([ - queryRange(url, 'sum(rate(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[1m]))', start, now, step).catch(() => []), - queryRange(url, 'sum(rate(node_network_transmit_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[1m]))', start, now, step).catch(() => []) - ]); + const rx = rxResult.length > 0 ? parseFloat(rxResult[0].value[1]) : 0; + const tx = txResult.length > 0 ? parseFloat(txResult[0].value[1]) : 0; - const rxValues = rxResult.length > 0 ? rxResult[0].values : []; - const txValues = txResult.length > 0 ? txResult[0].values : []; - - return { - rx: calculateTrafficFromHistory(rxValues), - tx: calculateTrafficFromHistory(txValues) - }; + return { rx, tx }; + } catch (err) { + console.error(`[Prometheus] get24hTrafficSum error:`, err.message); + return { rx: 0, tx: 0 }; + } } /** @@ -417,34 +415,28 @@ async function get24hTrafficSum(url) { */ async function get24hServerTrafficSum(url, instance, job) { const node = resolveToken(instance); - const now = Math.floor(Date.now() / 1000); - const start = now - 86400; - const step = 60; - - const rxExpr = `sum(rate(node_network_receive_bytes_total{instance="${node}",job="${job}",device!~'tap.*|veth.*|br.*|docker.*|virbr*|podman.*|lo.*|vmbr.*|fwbr.|ip.*|gre.*|virbr.*|vnet.*'}[1m]))`; - const txExpr = `sum(rate(node_network_transmit_bytes_total{instance="${node}",job="${job}",device!~'tap.*|veth.*|br.*|docker.*|virbr*|podman.*|lo.*|vmbr.*|fwbr.|ip.*|gre.*|virbr.*|vnet.*'}[1m]))`; + + const rxExpr = `sum(increase(node_network_receive_bytes_total{instance="${node}",job="${job}",device!~'tap.*|veth.*|br.*|docker.*|virbr*|podman.*|lo.*|vmbr.*|fwbr.|ip.*|gre.*|virbr.*|vnet.*'}[24h]))`; + const txExpr = `sum(increase(node_network_transmit_bytes_total{instance="${node}",job="${job}",device!~'tap.*|veth.*|br.*|docker.*|virbr*|podman.*|lo.*|vmbr.*|fwbr.|ip.*|gre.*|virbr.*|vnet.*'}[24h]))`; const [rxResult, txResult] = await Promise.all([ - queryRange(url, rxExpr, start, now, step).catch(() => []), - queryRange(url, txExpr, start, now, step).catch(() => []) + query(url, rxExpr).catch(() => []), + query(url, txExpr).catch(() => []) ]); - const rxValues = rxResult.length > 0 ? rxResult[0].values : []; - const txValues = txResult.length > 0 ? txResult[0].values : []; + const rx = rxResult.length > 0 ? parseFloat(rxResult[0].value[1]) : 0; + const tx = txResult.length > 0 ? parseFloat(txResult[0].value[1]) : 0; - return { - rx: calculateTrafficFromHistory(rxValues), - tx: calculateTrafficFromHistory(txValues) - }; + return { rx, tx }; } /** * Get network traffic history (past 24h, 5-min intervals for chart) */ async function getNetworkHistory(url) { - const now = Math.floor(Date.now() / 1000); - const start = now - 86400; // 24h ago const step = 300; // 5 minutes for better resolution on chart + const now = Math.floor(Date.now() / 1000 / step) * step; // Sync to step boundary + const start = now - 86400; // 24h ago const [rxResult, txResult] = await Promise.all([ queryRange(url, @@ -496,9 +488,9 @@ function mergeNetworkHistories(histories) { * Get CPU usage history (past 1h, 1-min intervals) */ async function getCpuHistory(url) { - const now = Math.floor(Date.now() / 1000); - const start = now - 3600; // 1h ago const step = 60; // 1 minute + const now = Math.floor(Date.now() / 1000 / step) * step; // Sync to step boundary + const start = now - 3600; // 1h ago const result = await queryRange(url, '100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[1m])) * 100)',