bytelyst-devops-tools/dashboard/backend/src/lib/dashboard-alerts.ts

49 lines
1.4 KiB
TypeScript

import { appendFile } from 'fs/promises';
type AlertSeverity = 'info' | 'warn' | 'critical';
type AlertInstance = 'vijay' | 'bheem' | 'all';
interface DashboardWarningInput {
severity: AlertSeverity;
instance: AlertInstance;
message: string;
}
const DEDUPE_WINDOW_MS = 60 * 60 * 1000;
const recent = new Map<string, number>();
function severityToken(severity: AlertSeverity): string {
if (severity === 'critical') return 'CRITICAL';
if (severity === 'warn') return 'WARNING';
return 'INFO';
}
function alertKey(input: DashboardWarningInput): string {
return `${input.severity}\0${input.instance}\0${input.message}`;
}
function purgeExpired(now: number): void {
for (const [key, at] of recent) {
if (now - at > DEDUPE_WINDOW_MS) recent.delete(key);
}
}
export async function appendDashboardWarning(input: DashboardWarningInput, now = Date.now()): Promise<boolean> {
const logPath = process.env.HERMES_DASHBOARD_ALERT_LOG;
if (!logPath) return false;
purgeExpired(now);
const key = alertKey(input);
const previous = recent.get(key);
if (previous && now - previous <= DEDUPE_WINDOW_MS) return false;
recent.set(key, now);
const line = `${new Date(now).toISOString()} ${severityToken(input.severity)} instance=${input.instance} ${input.message}\n`;
await appendFile(logPath, line, 'utf8');
return true;
}
export function clearDashboardWarningDedupe(): void {
recent.clear();
}