如何在TypeScript应用中通过代码计算CPU使用率并定时写入文件?
解答
可行性判断
完全可行,但要注意20毫秒高频采样+持续文件写入带来的潜在性能问题:
- 单进程下采样本身的CPU开销极小,但如果用同步IO写文件,频繁的磁盘操作可能阻塞事件循环;
- 若系统本身处于高负载状态,高频采样会小幅增加CPU占用,建议先在目标环境做简单测试。
Node.js 实现方案
原生模块实现(无第三方依赖)
用Node.js内置的os模块,通过对比两次采样的CPU时间统计值计算使用率:
const os = require('os'); const { createWriteStream } = require('fs'); // 初始化追加模式的写入流,避免覆盖旧日志 const logStream = createWriteStream('./cpu_usage.log', { flags: 'a' }); // 记录上一次的CPU时间统计 let prevCpuTimes = os.cpus().map(cpu => cpu.times); function getCpuUsage() { const currCpuTimes = os.cpus().map(cpu => cpu.times); let totalUsage = 0; currCpuTimes.forEach((curr, idx) => { const prev = prevCpuTimes[idx]; // 计算两次采样的总时间差和空闲时间差 const totalDiff = Object.values(curr).reduce((a, b) => a + b) - Object.values(prev).reduce((a, b) => a + b); const idleDiff = curr.idle - prev.idle; // 单核心使用率 = (总时间差 - 空闲时间差) / 总时间差 * 100 const coreUsage = ((totalDiff - idleDiff) / totalDiff) * 100; totalUsage += coreUsage; }); // 返回多核平均使用率 return (totalUsage / currCpuTimes.length).toFixed(2); } // 定时采样写入 setInterval(() => { const usage = getCpuUsage(); const logLine = `${new Date().toISOString()} - CPU使用率: ${usage}%\n`; // 用流式写入避免同步IO阻塞 logStream.write(logLine, err => { if (err) console.error('日志写入失败:', err); }); // 更新上一次的CPU时间记录 prevCpuTimes = os.cpus().map(cpu => cpu.times); }, 20);
第三方库简化实现
如果不想自己写计算逻辑,可以用pidusage这类库直接获取CPU使用率(注意:默认采样间隔可能不同,需按需调整):
const pidusage = require('pidusage'); const { createWriteStream } = require('fs'); const logStream = createWriteStream('./cpu_usage.log', { flags: 'a' }); setInterval(async () => { // 获取当前进程的CPU使用率,如需系统级需额外处理 const stats = await pidusage(process.pid); const usage = stats.cpu.toFixed(2); const logLine = `${new Date().toISOString()} - CPU使用率: ${usage}%\n`; logStream.write(logLine, err => { if (err) console.error('日志写入失败:', err); }); }, 20);
重要优化点
- 不要用同步写文件:同步IO会阻塞Node.js的事件循环,优先用流式写入或批量缓存(比如攒10条日志再一次性写入);
- 日志轮转:长期运行的话,要配置日志轮转(比如按文件大小或时间分割),防止单个日志文件过大;
- 按需调整采样间隔:如果业务对延迟敏感,可在高峰时段适当降低采样频率,平衡监控精度和性能。
内容的提问来源于stack exchange,提问作者limor
相关产品推荐
相关产品推荐

