diff --git a/public/js/app.js b/public/js/app.js index ea5f18c..708bbba 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -976,6 +976,8 @@ 'seattle': [-122.3321, 47.6062], 'us chicago': [-87.6298, 41.8781], 'chicago': [-87.6298, 41.8781], + 'us houston': [-95.3698, 29.7604], + 'houston': [-95.3698, 29.7604], 'new york': [-74.0060, 40.7128], 'new york corp': [-74.0060, 40.7128], 'san francisco': [-122.4194, 37.7749], @@ -985,8 +987,8 @@ 'tokyo': [139.6917, 35.6895], 'singapore': [103.8198, 1.3521], 'sg': [103.8198, 1.3521], - 'germany': [10.4515, 51.1657], - 'de': [10.4515, 51.1657], + 'germany': [8.6821, 50.1109], + 'de': [8.6821, 50.1109], 'frankfurt': [8.6821, 50.1109], 'united kingdom': [-3.436, 55.3781], 'uk': [-3.436, 55.3781], @@ -1479,6 +1481,9 @@ const response = await fetch(url); if (!response.ok) throw new Error('Fetch failed'); const data = await response.json(); + currentServerDetail.memTotal = data.memTotal; + currentServerDetail.swapTotal = data.swapTotal; + currentServerDetail.rootFsTotal = data.rootFsTotal; renderServerDetail(data); } catch (err) { @@ -1676,6 +1681,11 @@ currentServerDetail.charts[metricKey] = chart; } + // 为百分比图表设置总量,允许 Y 轴显示实际物理占用数值 + if (metricKey === 'memUsedPct') chart.totalValue = currentServerDetail.memTotal; + if (metricKey === 'swapUsedPct') chart.totalValue = currentServerDetail.swapTotal; + if (metricKey === 'rootFsUsedPct') chart.totalValue = currentServerDetail.rootFsTotal; + try { const { instance, job, source } = currentServerDetail; let url = `/api/metrics/server-history?instance=${encodeURIComponent(instance)}&job=${encodeURIComponent(job)}&source=${encodeURIComponent(source)}&metric=${metricKey}`; diff --git a/public/js/chart.js b/public/js/chart.js index 9c6e593..b5a9f4e 100644 --- a/public/js/chart.js +++ b/public/js/chart.js @@ -477,6 +477,10 @@ class MetricChart { } else { label = v.toFixed(0) + this.unit; } + } else if (this.unit === '%' && this.totalValue) { + // 当提供了总量时,将百分比转换为实际数值显示(例如内存显示 2GB 而非 25%) + const absVal = v * (this.totalValue / 100); + label = window.formatBytes ? window.formatBytes(absVal) : absVal.toFixed(0); } else { label = (v >= 1000 ? (v / 1000).toFixed(1) + 'k' : v.toFixed(v < 10 && v > 0 ? 1 : 0)) + this.unit; } diff --git a/server/prometheus-service.js b/server/prometheus-service.js index 004d976..9a10d3b 100644 --- a/server/prometheus-service.js +++ b/server/prometheus-service.js @@ -558,6 +558,8 @@ async function getServerDetails(baseUrl, instance, job) { rootFsUsedPct: `100 - ((node_filesystem_avail_bytes{instance="${node}",job="${job}",mountpoint="/",fstype!~"rootfs|tmpfs"} * 100) / node_filesystem_size_bytes{instance="${node}",job="${job}",mountpoint="/",fstype!~"rootfs|tmpfs"})`, cpuCores: `count(count(node_cpu_seconds_total{instance="${node}",job="${job}"}) by (cpu))`, memTotal: `node_memory_MemTotal_bytes{instance="${node}",job="${job}"}`, + swapTotal: `node_memory_SwapTotal_bytes{instance="${node}",job="${job}"}`, + rootFsTotal: `node_filesystem_size_bytes{instance="${node}",job="${job}",mountpoint="/",fstype!~"rootfs|tmpfs"}`, uptime: `node_time_seconds{instance="${node}",job="${job}"} - node_boot_time_seconds{instance="${node}",job="${job}"}`, netRx: `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]))`, netTx: `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]))`,