From 30c94b226abed50f5c53f4b274ca1dd927a21c6c Mon Sep 17 00:00:00 2001 From: ekko <152005280+EKKOLearnAI@users.noreply.github.com> Date: Thu, 23 Apr 2026 19:49:31 +0800 Subject: [PATCH] fix: add periodic log rotation to prevent unbounded log growth (#160) Log rotation previously only ran at startup, causing logs to grow indefinitely on long-running processes (reported up to 71GB/day). Now checks file size every 60 seconds and truncates when exceeding 3MB. Fixes #155 Co-authored-by: Claude Opus 4.6 --- packages/server/src/services/logger.ts | 34 ++++++++++++++++---------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/server/src/services/logger.ts b/packages/server/src/services/logger.ts index 751b05e..fa68352 100644 --- a/packages/server/src/services/logger.ts +++ b/packages/server/src/services/logger.ts @@ -4,25 +4,33 @@ import { mkdirSync, statSync, truncateSync, openSync, readSync, closeSync, write import { homedir } from 'os' const MAX_LOG_SIZE = 3 * 1024 * 1024 // 3MB +const CHECK_INTERVAL = 60_000 // Check every minute const logDir = resolve(homedir(), '.hermes-web-ui', 'logs') mkdirSync(logDir, { recursive: true }) const logFile = resolve(logDir, 'server.log') -// Rotate log if it exceeds MAX_LOG_SIZE — truncate to keep the last half -try { - const stat = statSync(logFile) - if (stat.size > MAX_LOG_SIZE) { - const keepSize = Math.floor(MAX_LOG_SIZE / 2) - const fd = openSync(logFile, 'r') - const buf = Buffer.alloc(keepSize) - readSync(fd, buf, 0, keepSize, stat.size - keepSize) - closeSync(fd) - truncateSync(logFile, 0) - writeFileSync(logFile, buf) - } -} catch {} +function rotateIfNeeded() { + try { + const stat = statSync(logFile) + if (stat.size > MAX_LOG_SIZE) { + const keepSize = Math.floor(MAX_LOG_SIZE / 2) + const fd = openSync(logFile, 'r') + const buf = Buffer.alloc(keepSize) + readSync(fd, buf, 0, keepSize, stat.size - keepSize) + closeSync(fd) + truncateSync(logFile, 0) + writeFileSync(logFile, buf) + } + } catch {} +} + +// Rotate on startup +rotateIfNeeded() + +// Periodic rotation check — prevents unbounded log growth +setInterval(rotateIfNeeded, CHECK_INTERVAL) export const logger = pino({ level: process.env.LOG_LEVEL || 'info',