port-nimara-client-portal/server/plugins/memory-monitor.ts

68 lines
2.5 KiB
TypeScript

export default defineNitroPlugin((nitroApp) => {
let lastHeapSnapshot: number = 0;
const heapSnapshotThreshold = 1024 * 1024 * 1024 * 6; // 6GB
// Monitor memory usage every 30 seconds
setInterval(() => {
const memUsage = process.memoryUsage();
const heapUsedMB = Math.round(memUsage.heapUsed / 1024 / 1024);
const heapTotalMB = Math.round(memUsage.heapTotal / 1024 / 1024);
const rssMB = Math.round(memUsage.rss / 1024 / 1024);
const externalMB = Math.round(memUsage.external / 1024 / 1024);
console.log(`[Memory Monitor] Heap: ${heapUsedMB}MB / ${heapTotalMB}MB | RSS: ${rssMB}MB | External: ${externalMB}MB`);
// Warning if memory usage is high
if (memUsage.heapUsed > heapSnapshotThreshold) {
console.warn(`[Memory Monitor] High memory usage detected: ${heapUsedMB}MB`);
// Take heap snapshot if we haven't taken one in the last hour
const now = Date.now();
if (now - lastHeapSnapshot > 3600000) { // 1 hour
lastHeapSnapshot = now;
console.warn('[Memory Monitor] Memory usage critical - consider taking heap snapshot');
// Force garbage collection if available
if (global.gc) {
console.log('[Memory Monitor] Running garbage collection...');
global.gc();
// Log memory after GC
setTimeout(() => {
const afterGC = process.memoryUsage();
const heapFreed = memUsage.heapUsed - afterGC.heapUsed;
console.log(`[Memory Monitor] GC freed ${Math.round(heapFreed / 1024 / 1024)}MB`);
}, 1000);
}
}
}
}, 30000); // Every 30 seconds
// Monitor event loop lag
let lastCheck = Date.now();
setInterval(() => {
const now = Date.now();
const lag = now - lastCheck - 1000;
if (lag > 100) {
console.warn(`[Memory Monitor] Event loop lag detected: ${lag}ms`);
}
lastCheck = now;
}, 1000);
// Add memory info to health endpoint
nitroApp.hooks.hook('request', async (event) => {
if (event.node.req.url === '/api/health') {
const memUsage = process.memoryUsage();
event.context.memoryInfo = {
heapUsed: Math.round(memUsage.heapUsed / 1024 / 1024),
heapTotal: Math.round(memUsage.heapTotal / 1024 / 1024),
rss: Math.round(memUsage.rss / 1024 / 1024),
external: Math.round(memUsage.external / 1024 / 1024),
arrayBuffers: Math.round(memUsage.arrayBuffers / 1024 / 1024)
};
}
});
});