cpu-monitor.js
1 /** 2 * Real-time CPU usage monitor 3 * Samples os.cpus() tick counts every 200ms for instantaneous CPU utilization. 4 * Much more responsive than os.loadavg() which has a 30-60s exponential lag. 5 */ 6 7 import { cpus } from 'os'; 8 9 const SAMPLE_INTERVAL_MS = 200; 10 11 let currentCpuUsage = 0; // 0.0 to 1.0 normalized across all cores 12 let monitorInterval = null; 13 let lastSnapshot = null; 14 15 function takeCpuSnapshot() { 16 return cpus().map(cpu => ({ ...cpu.times })); 17 } 18 19 function computeUsage(before, after) { 20 let totalBusy = 0; 21 let totalTicks = 0; 22 23 for (let i = 0; i < before.length; i++) { 24 const b = before[i]; 25 const a = after[i]; 26 const idle = a.idle - b.idle; 27 const total = a.user - b.user + (a.nice - b.nice) + (a.sys - b.sys) + (a.irq - b.irq) + idle; 28 if (total > 0) { 29 totalBusy += total - idle; 30 totalTicks += total; 31 } 32 } 33 34 return totalTicks > 0 ? totalBusy / totalTicks : 0; 35 } 36 37 function startMonitor() { 38 if (monitorInterval) return; 39 lastSnapshot = takeCpuSnapshot(); 40 41 monitorInterval = setInterval(() => { 42 const now = takeCpuSnapshot(); 43 currentCpuUsage = computeUsage(lastSnapshot, now); 44 lastSnapshot = now; 45 }, SAMPLE_INTERVAL_MS); 46 47 // Don't prevent process exit 48 if (monitorInterval.unref) monitorInterval.unref(); 49 } 50 51 export function getCurrentCpuUsage() { 52 if (!monitorInterval) startMonitor(); 53 return currentCpuUsage; 54 } 55 56 export function stopCpuMonitor() { 57 if (monitorInterval) { 58 clearInterval(monitorInterval); 59 monitorInterval = null; 60 } 61 } 62 63 // Auto-start on import 64 startMonitor();