From 8c25f1735dfa99a29ec618791d5c7e1a009072cf Mon Sep 17 00:00:00 2001 From: CN-JS-HuiBai Date: Sun, 5 Apr 2026 19:45:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 4 ++++ public/js/app.js | 10 ++++++++-- server/prometheus-service.js | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index 36e0bb4..0b93e1c 100644 --- a/public/index.html +++ b/public/index.html @@ -519,6 +519,10 @@ 硬盘总量统计 0 GB +
+ 24h 网络总流量 + 0 B +
diff --git a/public/js/app.js b/public/js/app.js index 287cf8c..8ba7756 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -93,7 +93,8 @@ detailPartitionsContainer: document.getElementById('detailPartitionsContainer'), detailPartitionsList: document.getElementById('detailPartitionsList'), partitionSummary: document.getElementById('partitionSummary'), - partitionHeader: document.getElementById('partitionHeader') + partitionHeader: document.getElementById('partitionHeader'), + detailTraffic24h: document.getElementById('detailTraffic24h') }; // ---- State ---- @@ -915,6 +916,11 @@ dom.detailDiskTotal.textContent = formatBytes(totalDiskSize); } + // 24h Traffic Total + if (dom.detailTraffic24h && data.traffic24h) { + dom.detailTraffic24h.textContent = formatBytes((data.traffic24h.rx || 0) + (data.traffic24h.tx || 0)); + } + // Define metrics to show const cpuValueHtml = `
@@ -930,7 +936,7 @@ { key: 'rootFsUsedPct', label: '根分区使用率 (/)', value: formatPercent(data.rootFsUsedPct) }, { key: 'netRx', label: '网络接收速率 (RX)', value: formatBandwidth(data.netRx) }, { key: 'netTx', label: '网络发送速率 (TX)', value: formatBandwidth(data.netTx) }, - { key: 'networkTrend', label: '网络流量趋势 (24h)', value: '查看实时趋势线' }, + { key: 'networkTrend', label: '网络流量趋势 (24h)', value: '' }, { key: 'sockstatTcp', label: 'TCP 链接数 (Sockstat)', value: data.sockstatTcp.toFixed(0) }, { key: 'sockstatTcpMem', label: 'TCP 内存占用', value: formatBytes(data.sockstatTcpMem) } ]; diff --git a/server/prometheus-service.js b/server/prometheus-service.js index 969ea24..3ee638b 100644 --- a/server/prometheus-service.js +++ b/server/prometheus-service.js @@ -407,6 +407,32 @@ async function get24hTrafficSum(url) { }; } +/** + * Get total traffic for a specific server in the past 24h + */ +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 [rxResult, txResult] = await Promise.all([ + queryRange(url, rxExpr, start, now, step).catch(() => []), + queryRange(url, txExpr, start, now, step).catch(() => []) + ]); + + const rxValues = rxResult.length > 0 ? rxResult[0].values : []; + const txValues = txResult.length > 0 ? txResult[0].values : []; + + return { + rx: calculateTrafficFromHistory(rxValues), + tx: calculateTrafficFromHistory(txValues) + }; +} + /** * Get network traffic history (past 24h, 5-min intervals for chart) */ @@ -583,6 +609,15 @@ async function getServerDetails(baseUrl, instance, job) { delete results.partitions_size; delete results.partitions_free; + // Add 24h traffic sum for this specific server + try { + const traffic24h = await get24hServerTrafficSum(baseUrl, instance, job); + results.traffic24h = traffic24h; + } catch (e) { + console.error(`[Prometheus] Error fetching 24h traffic for ${node}:`, e.message); + results.traffic24h = { rx: 0, tx: 0 }; + } + return results; }