mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 19:06:34 +00:00
feat(store): event_log + audit_log rotation (30d/90d TTL + 100k row cap, 6h interval)
This commit is contained in:
parent
2d157e900d
commit
890271d4c8
2 changed files with 43 additions and 11 deletions
|
|
@ -175,22 +175,26 @@ export class Plugin extends BSBService<InstanceType<typeof Config>, typeof Event
|
||||||
|
|
||||||
registerRepo(this._repo);
|
registerRepo(this._repo);
|
||||||
|
|
||||||
const purged = this._repo.purgeOldKioskLogs(2);
|
// Startup purge
|
||||||
if (purged > 0) {
|
this.runPurge(obs);
|
||||||
obs.log.info("purged {count} kiosk logs older than 2h", { count: purged });
|
|
||||||
}
|
|
||||||
|
|
||||||
obs.log.info("store ready");
|
obs.log.info("store ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private runPurge(obs: Observable): void {
|
||||||
|
if (!this._repo) return;
|
||||||
|
const r = this._repo;
|
||||||
|
const kl = r.purgeKioskLogs(14);
|
||||||
|
const el = r.purgeEventLog(30, 100_000);
|
||||||
|
const al = r.purgeAuditLog(90);
|
||||||
|
if (kl + el + al > 0) {
|
||||||
|
obs.log.info("purge: {kl} kiosk_logs, {el} event_log, {al} audit_log", { kl, el, al });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async run(obs: Observable): Promise<void> {
|
async run(obs: Observable): Promise<void> {
|
||||||
this.purgeTimer = setInterval(() => {
|
// Purge every 6 hours.
|
||||||
if (!this._repo) return;
|
this.purgeTimer = setInterval(() => this.runPurge(obs), 6 * 60 * 60 * 1000);
|
||||||
const purged = this._repo.purgeOldKioskLogs(2);
|
|
||||||
if (purged > 0) {
|
|
||||||
obs.log.info("purged {count} kiosk logs older than 2h", { count: purged });
|
|
||||||
}
|
|
||||||
}, 10 * 60 * 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async dispose(): Promise<void> {
|
async dispose(): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -1722,6 +1722,34 @@ export class Repository {
|
||||||
this.prep("UPDATE event_log SET forwarded_to_nodered = 1 WHERE id = ?").run(eventId);
|
this.prep("UPDATE event_log SET forwarded_to_nodered = 1 WHERE id = ?").run(eventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete event_log rows older than `days` AND trim to `maxRows` total.
|
||||||
|
* Returns the number of rows deleted.
|
||||||
|
*/
|
||||||
|
purgeEventLog(days: number = 30, maxRows: number = 100_000): number {
|
||||||
|
const cutoff = new Date(Date.now() - days * 86_400_000).toISOString();
|
||||||
|
const r1 = this.db.prepare("DELETE FROM event_log WHERE received_at < ?").run(cutoff);
|
||||||
|
// Trim to maxRows by deleting oldest beyond the cap.
|
||||||
|
const r2 = this.db.prepare(
|
||||||
|
`DELETE FROM event_log WHERE id NOT IN (
|
||||||
|
SELECT id FROM event_log ORDER BY received_at DESC LIMIT ?
|
||||||
|
)`,
|
||||||
|
).run(maxRows);
|
||||||
|
return Number(r1.changes) + Number(r2.changes);
|
||||||
|
}
|
||||||
|
|
||||||
|
purgeAuditLog(days: number = 90): number {
|
||||||
|
const cutoff = new Date(Date.now() - days * 86_400_000).toISOString();
|
||||||
|
const r = this.db.prepare("DELETE FROM audit_log WHERE ts < ?").run(cutoff);
|
||||||
|
return Number(r.changes);
|
||||||
|
}
|
||||||
|
|
||||||
|
purgeKioskLogs(days: number = 14): number {
|
||||||
|
const cutoff = new Date(Date.now() - days * 86_400_000).toISOString();
|
||||||
|
const r = this.db.prepare("DELETE FROM kiosk_logs WHERE received_at < ?").run(cutoff);
|
||||||
|
return Number(r.changes);
|
||||||
|
}
|
||||||
|
|
||||||
queryEvents(filters: EventQueryFilters): { events: EventLog[]; total: number } {
|
queryEvents(filters: EventQueryFilters): { events: EventLog[]; total: number } {
|
||||||
const where: string[] = [];
|
const where: string[] = [];
|
||||||
const params: (string | number)[] = [];
|
const params: (string | number)[] = [];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue