UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

348 lines 12.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AlertManager = void 0; const events_1 = require("events"); const alert_history_manager_1 = require("./alert-history-manager"); const alert_rule_manager_1 = require("./alert-rule-manager"); class AlertManager extends events_1.EventEmitter { constructor(config) { super(); this.alerts = new Map(); this.isRunning = false; this.config = { maxAlertsInMemory: 1000, maxHistoryEntries: 10000, autoAckTimeout: 24 * 60 * 60 * 1000, autoResolveTimeout: 7 * 24 * 60 * 60 * 1000, persistenceEnabled: true, persistenceFile: '.polyv-alerts/alerts.json', notifications: { soundEnabled: true, visualEnabled: true, desktopEnabled: false, emailEnabled: false, volume: 0.7, minLevel: 'warning' }, defaultCooldown: 5 * 60 * 1000, performance: { maxProcessingRate: 100, batchSize: 10, processingInterval: 1000 }, ...config }; this.historyManager = new alert_history_manager_1.AlertHistoryManager(this.config); this.ruleManager = new alert_rule_manager_1.AlertRuleManager(); this.setupEventHandlers(); this.setupCleanupInterval(); } setupEventHandlers() { this.ruleManager.on('rule:triggered', (data) => { if (data.result.alert) { this.createAlert(data.result.alert); } this.emit('rule:triggered', data); }); this.historyManager.on('entry:added', (data) => { this.emit('alert:history-updated', data); }); this.historyManager.on('action:recorded', (data) => { this.emit('alert:action-recorded', data); }); } setupCleanupInterval() { this.cleanupInterval = setInterval(() => { this.performAutomaticCleanup(); }, 60 * 60 * 1000); } start() { if (this.isRunning) return; this.isRunning = true; this.ruleManager.start(); this.evaluationInterval = setInterval(() => { this.evaluateAlerts(); }, this.config.performance.processingInterval); this.emit('manager:started'); } stop() { if (!this.isRunning) return; this.isRunning = false; this.ruleManager.stop(); if (this.evaluationInterval) { clearInterval(this.evaluationInterval); this.evaluationInterval = undefined; } this.emit('manager:stopped'); } createAlert(alertData) { const alert = { id: this.generateAlertId(), timestamp: Date.now(), acknowledged: false, status: 'active', ...alertData }; this.alerts.set(alert.id, alert); this.historyManager.addAlert(alert, 'created'); this.enforceMemoryLimits(); this.emit('alert:created', { alert }); this.emit('alert:new', { alert }); return alert; } acknowledgeAlert(alertId, user) { const alert = this.alerts.get(alertId); if (!alert || alert.acknowledged) return false; alert.acknowledged = true; alert.acknowledgedAt = Date.now(); if (user) { alert.acknowledgedBy = user; } if (alert.status === 'active') { alert.status = 'acknowledged'; } this.historyManager.recordAction(alertId, 'acknowledged', user); this.emit('alert:acknowledged', { alertId, alert, user }); return true; } resolveAlert(alertId, user) { const alert = this.alerts.get(alertId); if (!alert || alert.status === 'resolved') return false; alert.status = 'resolved'; alert.resolvedAt = Date.now(); if (!alert.acknowledged) { alert.acknowledged = true; alert.acknowledgedAt = Date.now(); if (user) { alert.acknowledgedBy = user; } } this.historyManager.recordAction(alertId, 'resolved', user); this.emit('alert:resolved', { alertId, alert, user }); return true; } ignoreAlert(alertId, user) { const alert = this.alerts.get(alertId); if (!alert) return false; alert.status = 'ignored'; alert.acknowledgedAt = Date.now(); if (user) { alert.acknowledgedBy = user; } this.historyManager.recordAction(alertId, 'ignored', user); this.emit('alert:ignored', { alertId, alert, user }); return true; } deleteAlert(alertId) { const alert = this.alerts.get(alertId); if (!alert) return false; this.alerts.delete(alertId); this.historyManager.recordAction(alertId, 'deleted'); this.emit('alert:deleted', { alertId, alert }); return true; } addAlertNotes(alertId, notes, user) { const alert = this.alerts.get(alertId); if (!alert) return false; const timestamp = new Date().toISOString(); const noteEntry = user ? `[${timestamp}] ${user}: ${notes}` : `[${timestamp}] ${notes}`; if (alert.notes) { alert.notes += '\n' + noteEntry; } else { alert.notes = noteEntry; } this.historyManager.recordAction(alertId, 'notes-added', user, { notes }); this.emit('alert:notes-added', { alertId, alert, notes, user }); return true; } getAlerts() { return Array.from(this.alerts.values()); } getAlert(alertId) { return this.alerts.get(alertId); } getFilteredAlerts(filter) { const alerts = this.getAlerts(); if (!filter) return alerts; return alerts.filter(alert => { if (filter.levels?.length && !filter.levels.includes(alert.level)) { return false; } if (filter.types?.length && !filter.types.includes(alert.type)) { return false; } if (filter.statuses?.length && !filter.statuses.includes(alert.status)) { return false; } if (filter.sources?.length && !filter.sources.includes(alert.source)) { return false; } if (filter.channelIds?.length && !filter.channelIds.includes(alert.channelId || '')) { return false; } if (filter.timeRange) { if (alert.timestamp < filter.timeRange.start || alert.timestamp > filter.timeRange.end) { return false; } } if (filter.searchText) { const searchText = filter.searchText.toLowerCase(); return alert.title.toLowerCase().includes(searchText) || alert.message.toLowerCase().includes(searchText) || alert.source.toLowerCase().includes(searchText); } if (filter.acknowledgedOnly && !alert.acknowledged) { return false; } if (filter.unacknowledgedOnly && alert.acknowledged) { return false; } return true; }); } acknowledgeBatch(alertIds, user) { const result = { success: [], failed: [] }; alertIds.forEach(alertId => { if (this.acknowledgeAlert(alertId, user)) { result.success.push(alertId); } else { result.failed.push(alertId); } }); this.emit('alert:batch-acknowledged', { success: result.success, failed: result.failed, user }); return result; } resolveBatch(alertIds, user) { const result = { success: [], failed: [] }; alertIds.forEach(alertId => { if (this.resolveAlert(alertId, user)) { result.success.push(alertId); } else { result.failed.push(alertId); } }); this.emit('alert:batch-resolved', { success: result.success, failed: result.failed, user }); return result; } clearAllAlerts() { const count = this.alerts.size; this.alerts.clear(); this.historyManager.recordAction('all', 'cleared'); this.emit('alert:all-cleared', { count }); return count; } evaluateAlerts(context) { if (!context) { context = { timestamp: Date.now(), alertHistory: this.getAlerts() }; } const results = this.ruleManager.evaluateRules(context); results.forEach(result => { if (result.triggered && result.alert) { this.createAlert(result.alert); } }); } getStatistics() { return this.historyManager.getStatistics(); } getRecentActivity(hours = 24) { return this.historyManager.getRecentActivity(hours); } exportAlerts(format = 'json') { return this.historyManager.exportHistory(format); } importAlerts(data, format = 'json', merge = true) { return this.historyManager.importHistory(data, format, merge); } getAlertHistory(filter, limit, offset = 0) { return this.historyManager.getHistory(filter, limit, offset); } searchAlertHistory(searchText, searchFields = ['title', 'message'], limit = 100) { return this.historyManager.searchHistory(searchText, searchFields, limit); } getRuleManager() { return this.ruleManager; } getHistoryManager() { return this.historyManager; } performAutomaticCleanup() { const now = Date.now(); if (this.config.autoAckTimeout) { const autoAckCutoff = now - this.config.autoAckTimeout; this.alerts.forEach(alert => { if (!alert.acknowledged && alert.timestamp < autoAckCutoff) { this.acknowledgeAlert(alert.id, 'system'); } }); } if (this.config.autoResolveTimeout) { const autoResolveCutoff = now - this.config.autoResolveTimeout; this.alerts.forEach(alert => { if (alert.status !== 'resolved' && alert.timestamp < autoResolveCutoff) { this.resolveAlert(alert.id, 'system'); } }); } const resolvedCutoff = now - (24 * 60 * 60 * 1000); const alertsToRemove = []; this.alerts.forEach((alert, id) => { if (alert.status === 'resolved' && alert.resolvedAt && alert.resolvedAt < resolvedCutoff) { alertsToRemove.push(id); } }); alertsToRemove.forEach(id => this.alerts.delete(id)); if (alertsToRemove.length > 0) { this.emit('alert:cleanup', { removedCount: alertsToRemove.length }); } } enforceMemoryLimits() { if (this.alerts.size <= this.config.maxAlertsInMemory) return; const sortedAlerts = Array.from(this.alerts.entries()) .sort((a, b) => { if (a[1].status === 'resolved' && b[1].status !== 'resolved') return -1; if (a[1].status !== 'resolved' && b[1].status === 'resolved') return 1; return a[1].timestamp - b[1].timestamp; }); const toRemove = sortedAlerts.slice(0, this.alerts.size - this.config.maxAlertsInMemory); toRemove.forEach(([id]) => this.alerts.delete(id)); if (toRemove.length > 0) { this.emit('alert:memory-cleanup', { removedCount: toRemove.length }); } } generateAlertId() { return `alert-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; } async destroy() { this.stop(); if (this.cleanupInterval) { clearInterval(this.cleanupInterval); this.cleanupInterval = undefined; } await this.historyManager.destroy(); await this.ruleManager.destroy(); this.alerts.clear(); this.removeAllListeners(); this.emit('manager:destroyed'); } } exports.AlertManager = AlertManager; //# sourceMappingURL=alert-manager.js.map