68 lines
2.5 KiB
TypeScript
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)
|
|
};
|
|
}
|
|
});
|
|
});
|