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