my harness for niri
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

retain only 3 days worth of metrics

+39
+39
src/metrics.ts
··· 158 158 let db: Database.Database 159 159 const events: (MetricEvent & { id: number })[] = [] 160 160 const MAX_IN_MEMORY = 100 161 + const DEFAULT_METRICS_RETENTION_DAYS = 3 162 + const METRICS_PRUNE_INTERVAL_MS = 60 * 60_000 163 + 164 + let pruneTimer: ReturnType<typeof setInterval> | null = null 165 + 166 + function metricsRetentionDays(): number { 167 + const parsed = Number(process.env.METRICS_RETENTION_DAYS ?? DEFAULT_METRICS_RETENTION_DAYS) 168 + if (!Number.isFinite(parsed) || parsed <= 0) return DEFAULT_METRICS_RETENTION_DAYS 169 + return parsed 170 + } 171 + 172 + function metricsRetentionCutoff(days = metricsRetentionDays()): string { 173 + return new Date(Date.now() - days * 24 * 60 * 60_000).toISOString() 174 + } 175 + 176 + export function pruneOldMetrics(days = metricsRetentionDays()): number { 177 + if (!db) return 0 178 + 179 + const cutoff = metricsRetentionCutoff(days) 180 + try { 181 + const result = db.prepare("delete from metrics where createdAt < ?").run(cutoff) 182 + const deleted = result.changes 183 + if (deleted > 0) { 184 + console.log(`[metrics] pruned ${deleted} rows older than ${days} days`) 185 + db.pragma("wal_checkpoint(PASSIVE)") 186 + } 187 + return deleted 188 + } catch (err) { 189 + console.error("[metrics] failed to prune old metrics:", err) 190 + return 0 191 + } 192 + } 161 193 162 194 export function initMetricsDb(): void { 163 195 try { ··· 202 234 create index if not exists idx_metrics_created on metrics(createdAt desc); 203 235 create index if not exists idx_metrics_type_id on metrics(type, id desc); 204 236 `) 237 + pruneOldMetrics() 238 + if (!pruneTimer) { 239 + pruneTimer = setInterval(() => { 240 + pruneOldMetrics() 241 + }, METRICS_PRUNE_INTERVAL_MS) 242 + if (typeof pruneTimer.unref === "function") pruneTimer.unref() 243 + } 205 244 console.log("[metrics] ready") 206 245 } 207 246