UNPKG

memory-watch

Version:

Advanced Node.js memory monitoring with stack trace analysis, user code detection, and memory leak identification

123 lines 5.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateDiagnosticReport = generateDiagnosticReport; exports.getMemoryLeakIndicators = getMemoryLeakIndicators; const formatBytes_1 = require("./formatBytes"); /** * Generate a detailed diagnostic report from memory data */ function generateDiagnosticReport(data) { const lines = []; lines.push("🔍 MEMORY DIAGNOSTIC REPORT"); lines.push("================================"); lines.push(`📊 Overall Usage: ${(data.percentage * 100).toFixed(2)}% (${(0, formatBytes_1.formatBytes)(data.usedBytes)} / ${(0, formatBytes_1.formatBytes)(data.totalBytes)})`); lines.push(`⏰ Timestamp: ${data.timestamp.toISOString()}`); lines.push(""); // Memory Breakdown lines.push("📈 MEMORY BREAKDOWN:"); lines.push(` • Heap Used: ${(0, formatBytes_1.formatBytes)(data.breakdown.heapUsed)}`); lines.push(` • Heap Total: ${(0, formatBytes_1.formatBytes)(data.breakdown.heapTotal)}`); lines.push(` • RSS (Physical): ${(0, formatBytes_1.formatBytes)(data.breakdown.rss)}`); lines.push(` • External: ${(0, formatBytes_1.formatBytes)(data.breakdown.external)}`); lines.push(` • Array Buffers: ${(0, formatBytes_1.formatBytes)(data.breakdown.arrayBuffers)}`); lines.push(""); // Process Information if (data.context) { lines.push("🖥️ PROCESS INFO:"); lines.push(` • PID: ${data.context.pid}`); lines.push(` • Node.js: ${data.context.nodeVersion}`); lines.push(` • Platform: ${data.context.platform}`); lines.push(` • Uptime: ${formatUptime(data.context.uptime)}`); if (data.context.activeHandles !== undefined) { lines.push(` • Active Handles: ${data.context.activeHandles}`); } if (data.context.activeRequests !== undefined) { lines.push(` • Active Requests: ${data.context.activeRequests}`); } if (data.context.cpuUsage) { lines.push(` • CPU User: ${data.context.cpuUsage.user.toFixed(3)}s`); lines.push(` • CPU System: ${data.context.cpuUsage.system.toFixed(3)}s`); } lines.push(""); // Stack Trace Analysis if (data.context.stackTrace && data.context.stackTrace.length > 0) { lines.push("🎯 POTENTIAL SOURCES (Stack Trace):"); data.context.stackTrace.forEach((trace, index) => { if (trace.fileName && trace.lineNumber) { lines.push(` ${index + 1}. ${trace.functionName} (${trace.fileName}:${trace.lineNumber}:${trace.columnNumber})`); } else { lines.push(` ${index + 1}. ${trace.functionName}`); } }); lines.push(""); } if (data.context.triggerSource) { lines.push(`🔎 Trigger Source: ${data.context.triggerSource}`); lines.push(""); } } // Recommendations lines.push("💡 RECOMMENDATIONS:"); if (data.breakdown.heapUsed / data.breakdown.heapTotal > 0.9) { lines.push(" ⚠️ Heap usage is very high - possible memory leak"); } if (data.context?.activeHandles && data.context.activeHandles > 50) { lines.push(" ⚠️ Many active handles - check for unclosed timers/servers"); } if (data.context?.activeRequests && data.context.activeRequests > 20) { lines.push(" ⚠️ Many active requests - possible request bottleneck"); } if (data.breakdown.external > data.breakdown.heapUsed) { lines.push(" ⚠️ High external memory usage - check C++ addons or buffers"); } if (data.breakdown.arrayBuffers > 100 * 1024 * 1024) { // > 100MB lines.push(" ⚠️ Large ArrayBuffer usage detected"); } lines.push(""); lines.push("================================"); return lines.join("\n"); } /** * Format uptime seconds to human readable format */ function formatUptime(seconds) { const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const secs = Math.floor(seconds % 60); if (hours > 0) { return `${hours}h ${minutes}m ${secs}s`; } else if (minutes > 0) { return `${minutes}m ${secs}s`; } else { return `${secs}s`; } } /** * Get memory leak indicators */ function getMemoryLeakIndicators(data) { const indicators = []; // High heap usage if (data.breakdown.heapUsed / data.breakdown.heapTotal > 0.85) { indicators.push("High heap utilization (>85%)"); } // RSS much larger than heap if (data.breakdown.rss > data.breakdown.heapTotal * 2) { indicators.push("RSS significantly larger than heap"); } // Many active handles if (data.context?.activeHandles && data.context.activeHandles > 100) { indicators.push(`Too many active handles (${data.context.activeHandles})`); } // Large external memory if (data.breakdown.external > 50 * 1024 * 1024) { // > 50MB indicators.push(`High external memory usage (${(0, formatBytes_1.formatBytes)(data.breakdown.external)})`); } return indicators; } //# sourceMappingURL=diagnostic.js.map