UNPKG

@sailboat-computer/event-bus

Version:

Standardized event bus for sailboat computer v3 with resilience features and offline capabilities

232 lines (198 loc) 6.82 kB
/** * Monitoring and alerting example * * This example demonstrates how to use the monitoring and alerting features of the event bus. */ import { createEventBus, EventPriority, EventCategory, AlertType, Alert } from '../src'; // Define a simple event type interface TestEvent { id: string; value: number; timestamp: string; } // Create an alert handler that logs alerts function createAlertHandler() { return (alert: Alert) => { const statusText = alert.resolved ? 'RESOLVED' : 'ACTIVE'; const severityText = alert.severity.toUpperCase(); console.log(`[${statusText}] [${severityText}] ${alert.message}`); if (alert.details) { console.log(' Details:', JSON.stringify(alert.details, null, 2)); } }; } // Create a handler that will fail for certain events function createFailingHandler() { return (event: any) => { const testEvent = event.data as TestEvent; console.log(`Processing event: ${testEvent.id} = ${testEvent.value}`); // Simulate a failure for events with value > 50 if (testEvent.value > 50) { throw new Error(`Failed to process event with value ${testEvent.value}`); } console.log(`Successfully processed event: ${testEvent.id}`); }; } async function runExample() { console.log('Starting monitoring example...'); // Create event bus with monitoring enabled const eventBus = createEventBus({ adapter: { type: 'memory', config: { serviceName: 'monitoring-example', simulateLatency: true, latencyRange: [50, 200] // Simulate high latency to trigger processing time alerts } }, offlineBuffer: { maxSize: 100, priorityRetention: true }, metrics: { enabled: true, detailedTimings: true }, deadLetterQueue: { enabled: true, maxSize: 100, maxAttempts: 3 }, monitoring: { enabled: true, alertThresholds: { failedPublishesThreshold: 5, // 5% deadLetterQueueSizeThreshold: 2, reconnectionAttemptsThreshold: 3, processingTimeThreshold: 100 // 100ms }, checkInterval: 1000 // Check every second for demo purposes } }); // Initialize event bus await eventBus.initialize({ adapter: { type: 'memory', config: { serviceName: 'monitoring-example', simulateLatency: true, latencyRange: [50, 200] } }, offlineBuffer: { maxSize: 100, priorityRetention: true }, metrics: { enabled: true, detailedTimings: true }, deadLetterQueue: { enabled: true, maxSize: 100, maxAttempts: 3 }, monitoring: { enabled: true, alertThresholds: { failedPublishesThreshold: 5, deadLetterQueueSizeThreshold: 2, reconnectionAttemptsThreshold: 3, processingTimeThreshold: 100 }, checkInterval: 1000 } }); console.log('Event bus initialized with monitoring enabled'); // Register alert handler const handlerId = eventBus.registerAlertHandler(createAlertHandler()); console.log(`Registered alert handler with ID: ${handlerId}`); // Subscribe to events with a handler that will fail for some events await eventBus.subscribe<TestEvent>('test.event.v1', createFailingHandler()); console.log('Subscribed to test.event.v1 events'); // Publish some events const events = [ { id: 'event-1', value: 25, timestamp: new Date().toISOString() }, { id: 'event-2', value: 75, timestamp: new Date().toISOString() }, // Will fail { id: 'event-3', value: 30, timestamp: new Date().toISOString() }, { id: 'event-4', value: 90, timestamp: new Date().toISOString() }, // Will fail { id: 'event-5', value: 40, timestamp: new Date().toISOString() } ]; // Publish each event for (const event of events) { try { console.log(`Publishing event: ${event.id} = ${event.value}`); await eventBus.publish<TestEvent>( 'test.event.v1', event, { priority: EventPriority.NORMAL, category: EventCategory.DATA, tags: ['test', `value-${event.value}`] } ); console.log(`Published event: ${event.id}`); } catch (error) { console.error(`Failed to publish event: ${error.message}`); } // Wait a bit between events await new Promise(resolve => setTimeout(resolve, 200)); } // Wait for events to be processed and alerts to be generated console.log('\nWaiting for alerts to be generated...'); await new Promise(resolve => setTimeout(resolve, 2000)); // Get active alerts console.log('\nActive alerts:'); const activeAlerts = eventBus.getActiveAlerts(); if (activeAlerts.length === 0) { console.log('No active alerts'); } else { for (const alert of activeAlerts) { console.log(`- [${alert.severity}] ${alert.message}`); } } // Get alert history console.log('\nAlert history:'); const alertHistory = eventBus.getAlertHistory(); if (alertHistory.length === 0) { console.log('No alert history'); } else { for (const alert of alertHistory) { const statusText = alert.resolved ? 'RESOLVED' : 'ACTIVE'; console.log(`- [${statusText}] [${alert.severity}] ${alert.message}`); } } // Get metrics const metrics = eventBus.getMetrics(); console.log('\nEvent Bus Metrics:'); console.log(`- Published events: ${metrics.publishedEvents}`); console.log(`- Failed publishes: ${metrics.failedPublishes}`); console.log(`- Processed events: ${metrics.processedEvents}`); console.log(`- Dead letter queue size: ${(metrics as any).deadLetterQueueSize}`); console.log(`- Dead letter queue events: ${(metrics as any).deadLetterQueueEvents}`); console.log(`- Average processing time: ${(metrics as any).averageProcessingTime.toFixed(2)}ms`); // Filter alerts by type console.log('\nProcessing time alerts:'); const processingTimeAlerts = eventBus.getAlertHistory(undefined, AlertType.PROCESSING_TIME); if (processingTimeAlerts.length === 0) { console.log('No processing time alerts'); } else { for (const alert of processingTimeAlerts) { console.log(`- [${alert.severity}] ${alert.message}`); } } // Clear alert history console.log('\nClearing alert history...'); eventBus.clearAlertHistory(); // Verify alert history is cleared const remainingAlerts = eventBus.getAlertHistory(); console.log(`Alert history size after clearing: ${remainingAlerts.length}`); // Close the event bus await eventBus.close(); console.log('\nMonitoring example completed'); } // Run the example runExample().catch(error => { console.error('Example failed:', error); process.exit(1); });