Skip to main content
Glama
ooples

MCP Console Automation Server

MonitoringSystem.ts13.2 kB
import { EventEmitter } from 'events'; import { AnomalyDetector } from './AnomalyDetector.js'; import { AlertManager } from './AlertManager.js'; import { AuditLogger } from './AuditLogger.js'; import { PerformanceProfiler } from './PerformanceProfiler.js'; import { Logger } from '../utils/logger.js'; import { SystemMetrics, Alert, Anomaly, AuditEvent, LogEntry, PerformanceProfile, SLAConfig, MonitoringOptions, } from '../types/index.js'; interface MonitoringConfig { anomalyDetection: { enabled: boolean; windowSize: number; confidenceLevel: number; }; alerting: { enabled: boolean; channels: Array<{ type: 'email' | 'webhook' | 'slack' | 'console'; config: Record<string, any>; }>; }; auditing: { enabled: boolean; logDirectory: string; encryption: boolean; retention: number; }; performance: { enabled: boolean; samplingInterval: number; profileDuration: number; }; } export class MonitoringSystem extends EventEmitter { private logger: Logger; private config: MonitoringConfig; private isInitialized: boolean = false; private isRunning: boolean = false; // Monitoring components private anomalyDetector?: AnomalyDetector; private alertManager?: AlertManager; private auditLogger?: AuditLogger; private performanceProfiler?: PerformanceProfiler; // Active monitoring sessions private monitoringSessions: Map< string, { sessionId: string; profileId?: string; startTime: Date; options: MonitoringOptions; } > = new Map(); constructor(config?: Partial<MonitoringConfig>) { super(); this.logger = new Logger('MonitoringSystem'); this.config = { anomalyDetection: { enabled: false, windowSize: 100, confidenceLevel: 0.95, }, alerting: { enabled: false, channels: [ { type: 'console', config: {}, }, ], }, auditing: { enabled: false, logDirectory: './logs/audit', encryption: false, retention: 365, }, performance: { enabled: false, samplingInterval: 1000, profileDuration: 300, }, ...config, }; } // Initialize monitoring components async initialize(): Promise<void> { if (this.isInitialized) { this.logger.warn('Monitoring system already initialized'); return; } try { this.logger.info('Initializing monitoring system...'); // Initialize anomaly detection if (this.config.anomalyDetection.enabled) { this.anomalyDetector = new AnomalyDetector({ enabled: true, statisticalConfig: { windowSize: this.config.anomalyDetection.windowSize, confidenceLevel: this.config.anomalyDetection.confidenceLevel, seasonalityPeriod: 24, }, }); this.setupAnomalyDetectionEventHandlers(); } // Initialize alert management if (this.config.alerting.enabled) { this.alertManager = new AlertManager(); this.setupAlertingEventHandlers(); // Setup notification channels this.config.alerting.channels.forEach((channel, index) => { this.alertManager!.addNotificationChannel(`channel-${index}`, { type: channel.type as any, config: channel.config, enabled: true, }); }); } // Initialize audit logging if (this.config.auditing.enabled) { this.auditLogger = new AuditLogger({ enabled: true, logDirectory: this.config.auditing.logDirectory, encryption: { enabled: this.config.auditing.encryption, algorithm: 'aes-256-cbc', key: process.env.AUDIT_ENCRYPTION_KEY || 'default-key', }, retention: { days: this.config.auditing.retention, maxFileSizeMB: 100, compressionEnabled: true, }, }); await this.auditLogger.initialize(); } // Initialize performance profiler if (this.config.performance.enabled) { this.performanceProfiler = new PerformanceProfiler({ enabled: true, samplingInterval: this.config.performance.samplingInterval, profileDuration: this.config.performance.profileDuration, }); this.setupPerformanceEventHandlers(); } this.isInitialized = true; this.logger.info('Monitoring system initialized successfully'); } catch (error) { this.logger.error(`Failed to initialize monitoring system: ${error}`); throw error; } } // Start monitoring async start(): Promise<void> { if (!this.isInitialized) { await this.initialize(); } if (this.isRunning) { this.logger.warn('Monitoring system already running'); return; } this.logger.info('Starting monitoring system...'); if (this.anomalyDetector) { // Anomaly detector starts automatically } if (this.performanceProfiler) { // Performance profiler starts on demand } this.isRunning = true; this.emit('started'); this.logger.info('Monitoring system started'); } // Stop monitoring async stop(): Promise<void> { if (!this.isRunning) { this.logger.warn('Monitoring system not running'); return; } this.logger.info('Stopping monitoring system...'); if (this.auditLogger) { // Flush audit logger if it has a flush method if ( 'flush' in this.auditLogger && typeof this.auditLogger.flush === 'function' ) { await (this.auditLogger as any).flush(); } } this.isRunning = false; this.emit('stopped'); this.logger.info('Monitoring system stopped'); } // Start monitoring a session async startSessionMonitoring( sessionId: string, sessionData: { command: string; args: string[]; pid?: number; } & MonitoringOptions ): Promise<void> { const monitoringOptions = sessionData; const session = { sessionId, profileId: undefined as string | undefined, startTime: new Date(), options: monitoringOptions, }; // Start performance profiling if (monitoringOptions.enableProfiling && this.performanceProfiler) { const profileId = await this.performanceProfiler.startProfiling( sessionId, sessionData.command ); session.profileId = profileId; } // Log audit event if (monitoringOptions.enableAuditing && this.auditLogger) { await this.logAuditEvent({ timestamp: new Date(), eventType: 'session_created', sessionId, details: { command: sessionData.command, args: sessionData.args, pid: sessionData.pid, monitoring: monitoringOptions, }, riskLevel: 'low', }); } this.monitoringSessions.set(sessionId, session); this.emit('session-monitoring-started', { sessionId, ...sessionData }); } // Stop monitoring a session async stopSessionMonitoring(sessionId: string): Promise<void> { const session = this.monitoringSessions.get(sessionId); if (!session) { this.logger.warn(`No monitoring session found for ${sessionId}`); return; } // Finish performance profiling if (session.profileId && this.performanceProfiler) { const profile = await this.stopPerformanceProfiling(session.profileId); if (profile) { this.emit('performance-profile-ready', profile); } } // Log audit event if (session.options.enableAuditing && this.auditLogger) { await this.logAuditEvent({ timestamp: new Date(), eventType: 'session_stopped', sessionId, details: { duration: Date.now() - session.startTime.getTime(), }, riskLevel: 'low', }); } this.monitoringSessions.delete(sessionId); this.emit('session-monitoring-stopped', { sessionId }); } // Record an event for a session async recordEvent( sessionId: string, eventType: string, data: any ): Promise<void> { const session = this.monitoringSessions.get(sessionId); if (!session) { return; } // Detect anomalies if (session.options.enableAnomalyDetection && this.anomalyDetector) { if (eventType === 'output' && data.type === 'stderr') { // For now, just create a basic anomaly check const anomaly = data.text && data.text.toLowerCase().includes('error') ? { severity: 'medium' as const, description: 'Error detected in stderr output', } : null; if (anomaly) { this.emit('anomaly-detected', anomaly); if (this.alertManager) { await this.alertManager.createAlert({ id: `anomaly-${sessionId}-${Date.now()}`, type: 'anomaly', severity: anomaly.severity, title: `Anomaly detected in session ${sessionId}`, description: anomaly.description, sessionId, source: 'MonitoringSystem', timestamp: new Date(), resolved: false, }); } } } } // Log audit events for errors if ( eventType === 'error' && session.options.enableAuditing && this.auditLogger ) { await this.logAuditEvent({ timestamp: new Date(), eventType: 'error_detected', sessionId, details: data, riskLevel: 'medium', }); } } // Check if a session is being monitored isSessionBeingMonitored(sessionId: string): boolean { return this.monitoringSessions.has(sessionId); } // Get system metrics (stub for now) async getSystemMetrics(): Promise<SystemMetrics | null> { // Return null as we don't have metrics collector return null; } // Get session metrics async getSessionMetrics(sessionId: string): Promise<any> { const session = this.monitoringSessions.get(sessionId); if (!session) { return null; } return { sessionId, startTime: session.startTime, duration: Date.now() - session.startTime.getTime(), status: 'running', monitoringEnabled: session.options, }; } // Get alerts async getAlerts(): Promise<Alert[]> { if (!this.alertManager) { return []; } return this.alertManager.getAlerts(); } // Get dashboard data (stub) async getDashboard(): Promise<any> { return { totalSessions: this.monitoringSessions.size, alerts: await this.getAlerts(), }; } // Helper method for logging audit events private async logAuditEvent(event: AuditEvent): Promise<void> { if (!this.auditLogger) return; // AuditLogger might not have a log method, so we'll handle it gracefully if ( 'log' in this.auditLogger && typeof this.auditLogger.log === 'function' ) { await (this.auditLogger as any).log(event); } else { this.logger.debug('Audit event:', event); } } // Helper method for stopping performance profiling private async stopPerformanceProfiling( profileId: string ): Promise<PerformanceProfile | null> { if (!this.performanceProfiler) return null; // PerformanceProfiler might not have finishProfiling method if ( 'finishProfiling' in this.performanceProfiler && typeof this.performanceProfiler.finishProfiling === 'function' ) { return await (this.performanceProfiler as any).finishProfiling(profileId); } // Fallback: return a basic profile return { sessionId: profileId, command: 'unknown', startTime: new Date(), endTime: new Date(), duration: 0, metrics: { avgCpuUsage: 0, peakMemoryUsage: 0, totalDiskIO: 0, totalNetworkIO: 0, }, bottlenecks: [], }; } // Setup event handlers private setupAnomalyDetectionEventHandlers(): void { if (!this.anomalyDetector) return; this.anomalyDetector.on('anomaly', (anomaly: Anomaly) => { this.emit('anomaly', anomaly); }); } private setupAlertingEventHandlers(): void { if (!this.alertManager) return; this.alertManager.on('alert-created', (alert: Alert) => { this.emit('alert', alert); }); } private setupPerformanceEventHandlers(): void { if (!this.performanceProfiler) return; this.performanceProfiler.on('bottleneck-detected', (bottleneck: any) => { this.emit('performance-bottleneck', bottleneck); }); } // Cleanup async destroy(): Promise<void> { await this.stop(); if (this.auditLogger) { // Close audit logger if it has a close method if ( 'close' in this.auditLogger && typeof this.auditLogger.close === 'function' ) { await (this.auditLogger as any).close(); } } this.removeAllListeners(); this.monitoringSessions.clear(); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ooples/mcp-console-automation'

If you have feedback or need assistance with the MCP directory API, please join our Discord server