UNPKG

bodhi-node-profiler

Version:

A lightweight, zero-configuration performance profiler for Node.js applications with real-time dashboard

118 lines (101 loc) 3.14 kB
import pidusage from 'pidusage'; import { performance } from 'perf_hooks'; import { SystemStats, CpuMetrics, MemoryMetrics } from './types'; import os from 'os'; export class Stats { private latestStats: SystemStats; private eventLoopLag: number; private lastCpuUsage: { user: number; system: number }; private lastCpuCheck: number; constructor() { this.eventLoopLag = 0; this.lastCpuCheck = Date.now(); this.lastCpuUsage = process.cpuUsage(); this.latestStats = { timestamp: Date.now(), cpu: { percentage: '0', system: 0, user: 0 }, memory: { heapUsed: 0, heapTotal: 0, rss: 0, external: 0 }, eventLoopDelay: 0 }; this.startEventLoopMonitoring(); } private startEventLoopMonitoring(): void { let lastCheck = performance.now(); let minLag = Infinity; let maxLag = 0; let samples = 0; let totalLag = 0; setInterval(() => { const now = performance.now(); const delta = now - lastCheck; const lag = Math.max(0, delta - 1); // Update stats minLag = Math.min(minLag, lag); maxLag = Math.max(maxLag, lag); totalLag += lag; samples++; // Calculate average lag over the last interval if (samples >= 10) { // Average over 10 samples this.eventLoopLag = totalLag / samples; minLag = Infinity; maxLag = 0; totalLag = 0; samples = 0; } lastCheck = now; }, 10); // Sample every 10ms for better accuracy } private calculateCpuUsage(): CpuMetrics { const now = Date.now(); const currentCpuUsage = process.cpuUsage(); const userDiff = currentCpuUsage.user - this.lastCpuUsage.user; const systemDiff = currentCpuUsage.system - this.lastCpuUsage.system; const timeDiff = now - this.lastCpuCheck; this.lastCpuUsage = currentCpuUsage; this.lastCpuCheck = now; // Convert microseconds to milliseconds const totalUsage = (userDiff + systemDiff) / 1000; // Calculate percentage based on elapsed time and number of cores const numCores = os.cpus().length; const maxTime = timeDiff * numCores * 1000; // Convert to microseconds const percentage = ((totalUsage / maxTime) * 100).toFixed(1); return { percentage, system: systemDiff / 1000000, // Convert to seconds user: userDiff / 1000000 }; } public async collect(): Promise<SystemStats> { try { const memoryUsage = process.memoryUsage(); const cpu = this.calculateCpuUsage(); this.latestStats = { timestamp: Date.now(), cpu, memory: { heapUsed: memoryUsage.heapUsed, heapTotal: memoryUsage.heapTotal, rss: memoryUsage.rss, external: memoryUsage.external }, eventLoopDelay: this.eventLoopLag }; return this.latestStats; } catch (error) { console.error('Error collecting stats:', error); throw error; } } public getLatest(): SystemStats { return this.latestStats; } }