Add automatic retention purging for the Diagnostic and Audit logs
The diagnostic log already rings-buffer to 500 rows, but the audit log had no cap at all and would grow forever. Adds an opt-in age-based purge under Settings -> Logs: keep entries for N days, checked on a configurable interval (hourly through monthly), plus a manual "Purge now" button. Reuses the existing node-schedule-style reschedule-on-settings-change pattern from the secret/Tailscale expiry checkers, but as a plain setInterval since "how often" here is an interval rather than a specific daily time. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
af3f7e77d2
commit
10d123b18a
9 files changed
+281
No files matched your search
@@ -0,0 +1,49 @@
|
||||
import { getSettings, getInternalFlag, setInternalFlag } from "./settingsStore.js";
|
||||
import { purgeOldLogs } from "./logRetention.js";
|
||||
|
||||
const LAST_RUN_FLAG = "logRetentionLastRunAt";
|
||||
|
||||
async function runPurge(): Promise<void> {
|
||||
const { logRetention } = await getSettings();
|
||||
if (!logRetention.enabled) return;
|
||||
const result = await purgeOldLogs(logRetention.retentionDays);
|
||||
await setInternalFlag(LAST_RUN_FLAG, new Date().toISOString());
|
||||
if (result.diagDeleted || result.auditDeleted) {
|
||||
console.log(
|
||||
`[logRetention] purged ${result.diagDeleted} diagnostic log and ${result.auditDeleted} audit log entries older than ${logRetention.retentionDays} days`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let currentTimer: ReturnType<typeof setInterval> | null = null;
|
||||
|
||||
/** (Re)arms the periodic purge timer per the current settings. Call again after settings change. */
|
||||
export async function scheduleLogRetentionPurge(): Promise<void> {
|
||||
if (currentTimer) {
|
||||
clearInterval(currentTimer);
|
||||
currentTimer = null;
|
||||
}
|
||||
const { logRetention } = await getSettings();
|
||||
if (!logRetention.enabled) {
|
||||
console.log("[logRetention] automatic purge disabled");
|
||||
return;
|
||||
}
|
||||
const intervalMs = logRetention.intervalHours * 60 * 60 * 1000;
|
||||
currentTimer = setInterval(() => {
|
||||
runPurge().catch((err) => console.error("[logRetention] purge failed:", err));
|
||||
}, intervalMs);
|
||||
console.log(`[logRetention] automatic purge scheduled every ${logRetention.intervalHours}h, keeping ${logRetention.retentionDays} days`);
|
||||
}
|
||||
|
||||
/** Runs immediately at startup if a purge is overdue (e.g. the server was down past the interval), then arms the periodic timer. */
|
||||
export async function initLogRetentionScheduler(): Promise<void> {
|
||||
const { logRetention } = await getSettings();
|
||||
if (logRetention.enabled) {
|
||||
const lastRun = await getInternalFlag(LAST_RUN_FLAG);
|
||||
const dueAt = lastRun ? new Date(lastRun).getTime() + logRetention.intervalHours * 60 * 60 * 1000 : 0;
|
||||
if (Date.now() >= dueAt) {
|
||||
await runPurge().catch((err) => console.error("[logRetention] purge failed:", err));
|
||||
}
|
||||
}
|
||||
await scheduleLogRetentionPurge();
|
||||
}
|
||||
Reference in new issue
Block a user