Skip to content

Commit 86ba7af

Browse files
Add log rotation to prevent unbounded log growth
Rotates vibora.log when it exceeds 10MB, keeping up to 2 backups. This caps total log storage at ~30MB.
1 parent ea73bb7 commit 86ba7af

1 file changed

Lines changed: 35 additions & 2 deletions

File tree

server/lib/logger.ts

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
// Centralized logging for Vibora backend
22
// Outputs JSON lines to stdout and vibora.log file
33

4-
import { appendFileSync } from 'fs'
4+
import { appendFileSync, statSync, renameSync, unlinkSync } from 'fs'
55
import { join } from 'path'
6+
7+
// Log rotation settings
8+
const MAX_LOG_SIZE = 10 * 1024 * 1024 // 10MB
9+
const MAX_LOG_BACKUPS = 2 // Keep .1 and .2 backups
610
import { type LogEntry, type LogLevel, type Logger, LOG_LEVELS, formatLogEntry } from '../../shared/logger'
711
import { getViboraDir, ensureViboraDir } from './settings'
812

@@ -33,6 +37,34 @@ function getLogFile(): string | null {
3337
}
3438
}
3539

40+
// Rotate log file if it exceeds MAX_LOG_SIZE
41+
function rotateLogIfNeeded(logFile: string): void {
42+
try {
43+
const stats = statSync(logFile)
44+
if (stats.size < MAX_LOG_SIZE) return
45+
46+
// Rotate: delete oldest, shift others, rename current
47+
for (let i = MAX_LOG_BACKUPS; i >= 1; i--) {
48+
const older = `${logFile}.${i}`
49+
const newer = i === 1 ? logFile : `${logFile}.${i - 1}`
50+
try {
51+
if (i === MAX_LOG_BACKUPS) {
52+
unlinkSync(older)
53+
}
54+
} catch {
55+
// File doesn't exist, that's fine
56+
}
57+
try {
58+
renameSync(newer, older)
59+
} catch {
60+
// Source doesn't exist, that's fine
61+
}
62+
}
63+
} catch {
64+
// File doesn't exist yet or other error, skip rotation
65+
}
66+
}
67+
3668
/**
3769
* Core logging function - writes a log entry to stdout and vibora.log
3870
* Used by both the Logger class and /api/logs endpoint
@@ -43,10 +75,11 @@ export function writeEntry(entry: LogEntry): void {
4375
// Write to stdout (captured by daemon/nohup)
4476
console.log(line)
4577

46-
// Write to log file
78+
// Write to log file (with rotation)
4779
const logFile = getLogFile()
4880
if (logFile) {
4981
try {
82+
rotateLogIfNeeded(logFile)
5083
appendFileSync(logFile, line + '\n')
5184
} catch {
5285
// Ignore file write errors

0 commit comments

Comments
 (0)