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;
}