From 7d2704b14ee7c7f9f87c99334f079f2bba593df4 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Mon, 9 Mar 2026 19:05:41 +0800 Subject: [PATCH] =?UTF-8?q?fix(system-monitor):=20=E6=94=B9=E8=BF=9B?= =?UTF-8?q?=E8=BF=9B=E7=A8=8BCPU=E4=BD=BF=E7=94=A8=E7=8E=87=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E5=87=86=E7=A1=AE=E6=80=A7=E5=92=8C=E7=A8=B3=E5=AE=9A?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 优先使用Node.js内置的process.cpuUsage()计算当前进程CPU使用率,提高跨平台准确性 - 为外部进程ps命令添加错误处理,避免在BusyBox环境下报错干扰日志 - 更新Dockerfile安装procps工具以支持系统监控功能 - 同步更新版本号至2.11.1 --- Dockerfile | 4 +-- VERSION | 2 +- src/ui-modules/system-monitor.js | 45 ++++++++++++++++++++++++++------ 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 95023b9..15ca582 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,8 +19,8 @@ FROM node:20-alpine LABEL maintainer="AIClient2API Team" LABEL description="Docker image for AIClient2API server" -# 安装必要的系统工具(tar 用于更新功能,git 用于版本检查) -RUN apk add --no-cache tar git +# 安装必要的系统工具(tar 用于更新功能,git 用于版本检查,procps 用于系统监控) +RUN apk add --no-cache tar git procps # 设置工作目录 WORKDIR /app diff --git a/VERSION b/VERSION index 46b81d8..6ceb272 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.11.0 +2.11.1 diff --git a/src/ui-modules/system-monitor.js b/src/ui-modules/system-monitor.js index 23e25b7..a37fc40 100644 --- a/src/ui-modules/system-monitor.js +++ b/src/ui-modules/system-monitor.js @@ -57,8 +57,31 @@ export function getProcessCpuUsagePercent(pid) { const isWindows = process.platform === 'win32'; let cpuPercent = 0; - if (isWindows) { - // Windows 下使用 PowerShell 获取进程的 CPU 使用率 + // 优先处理当前进程,使用 Node.js 内置的 process.cpuUsage(),这在所有平台上都更准确且无需外部命令 + if (pid === process.pid) { + const usage = process.cpuUsage(); + const timestamp = Date.now(); + const totalMicroseconds = usage.user + usage.system; + const prevInfo = processCpuInfoMap.get(pid); + + if (prevInfo && prevInfo.totalMicroseconds !== undefined) { + const timeDiff = (timestamp - prevInfo.timestamp) * 1000; // 转换为微秒 + const processTimeDiff = totalMicroseconds - prevInfo.totalMicroseconds; + + if (timeDiff > 0) { + const cpuCount = os.cpus().length; + cpuPercent = (processTimeDiff / timeDiff) * 100; + // Node.js 返回的是所有核心累加的使用量,归一化到 0-100% + cpuPercent = cpuPercent / cpuCount; + } + } + + processCpuInfoMap.set(pid, { + totalMicroseconds, + timestamp + }); + } else if (isWindows) { + // Windows 下使用 PowerShell 获取其他进程的 CPU 使用率 // CPU = (Process.TotalProcessorTime / ElapsedTime) / ProcessorCount const command = `powershell -Command "Get-Process -Id ${pid} | Select-Object -ExpandProperty TotalProcessorTime | ForEach-Object { $_.TotalSeconds }"`; const output = execSync(command, { encoding: 'utf8' }).trim(); @@ -67,7 +90,7 @@ export function getProcessCpuUsagePercent(pid) { if (!isNaN(totalProcessorSeconds)) { const prevInfo = processCpuInfoMap.get(pid); - if (prevInfo) { + if (prevInfo && prevInfo.totalProcessorSeconds !== undefined) { const timeDiff = (timestamp - prevInfo.timestamp) / 1000; // 转换为秒 const processTimeDiff = totalProcessorSeconds - prevInfo.totalProcessorSeconds; @@ -85,11 +108,17 @@ export function getProcessCpuUsagePercent(pid) { }); } } else { - // Linux/macOS 使用 ps 命令直接获取 - const output = execSync(`ps -p ${pid} -o %cpu`, { encoding: 'utf8' }); - const lines = output.trim().split('\n'); - if (lines.length >= 2) { - cpuPercent = parseFloat(lines[1].trim()); + // Linux/macOS 使用 ps 命令获取其他进程的 CPU 使用率 + // 增加 2> /dev/null 以防在 BusyBox 等环境下报错干扰日志 + try { + const output = execSync(`ps -p ${pid} -o %cpu 2>/dev/null`, { encoding: 'utf8' }); + const lines = output.trim().split('\n'); + if (lines.length >= 2) { + cpuPercent = parseFloat(lines[1].trim()); + } + } catch (e) { + // 如果 ps -p 失败,尝试更通用的 ps 方式或直接忽略 + cpuPercent = 0; } }