memory-watch
Version:
Advanced Node.js memory monitoring with stack trace analysis, user code detection, and memory leak identification
123 lines • 5.3 kB
JavaScript
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
;