UNPKG

claude-flow-tbowman01

Version:

Enterprise-grade AI agent orchestration with ruv-swarm integration (Alpha Release)

305 lines (263 loc) â€ĸ 9 kB
/** * System Monitor - Real-time monitoring of system processes */ import chalk from 'chalk'; import type { ProcessManager } from './process-manager.js'; import { SystemEvents } from '../../../utils/types.js'; import { eventBus } from '../../../core/event-bus.js'; export class SystemMonitor { private processManager: ProcessManager; private events: any[] = []; private maxEvents = 100; private metricsInterval?: NodeJS.Timeout; constructor(processManager: ProcessManager) { this.processManager = processManager; this.setupEventListeners(); } private setupEventListeners(): void { // System events eventBus.on(SystemEvents.AGENT_SPAWNED, (data: any) => { this.addEvent({ type: 'agent_spawned', timestamp: Date.now(), data, level: 'info', }); }); eventBus.on(SystemEvents.AGENT_TERMINATED, (data: any) => { this.addEvent({ type: 'agent_terminated', timestamp: Date.now(), data, level: 'warning', }); }); eventBus.on(SystemEvents.TASK_ASSIGNED, (data: any) => { this.addEvent({ type: 'task_assigned', timestamp: Date.now(), data, level: 'info', }); }); eventBus.on(SystemEvents.TASK_COMPLETED, (data: any) => { this.addEvent({ type: 'task_completed', timestamp: Date.now(), data, level: 'success', }); }); eventBus.on(SystemEvents.TASK_FAILED, (data: any) => { this.addEvent({ type: 'task_failed', timestamp: Date.now(), data, level: 'error', }); }); eventBus.on(SystemEvents.SYSTEM_ERROR, (data: any) => { this.addEvent({ type: 'system_error', timestamp: Date.now(), data, level: 'error', }); }); // Process manager events this.processManager.on('processStarted', ({ processId, process }) => { this.addEvent({ type: 'process_started', timestamp: Date.now(), data: { processId, processName: process.name }, level: 'success', }); }); this.processManager.on('processStopped', ({ processId }) => { this.addEvent({ type: 'process_stopped', timestamp: Date.now(), data: { processId }, level: 'warning', }); }); this.processManager.on('processError', ({ processId, error }) => { this.addEvent({ type: 'process_error', timestamp: Date.now(), data: { processId, error: error instanceof Error ? error.message : String(error) }, level: 'error', }); }); } private addEvent(event: any): void { this.events.unshift(event); if (this.events.length > this.maxEvents) { this.events.pop(); } } start(): void { // Start collecting metrics this.metricsInterval = setInterval(() => { this.collectMetrics(); }, 5000); } stop(): void { if (this.metricsInterval) { clearInterval(this.metricsInterval); } } private collectMetrics(): void { // Collect system metrics const processes = this.processManager.getAllProcesses(); for (const process of processes) { if (process.status === 'running') { // Simulate metrics collection (would integrate with actual monitoring) process.metrics = { ...process.metrics, cpu: Math.random() * 50, memory: Math.random() * 200, uptime: process.startTime ? Date.now() - process.startTime : 0, }; } } } getRecentEvents(count: number = 10): any[] { return this.events.slice(0, count); } printEventLog(count: number = 20): void { console.log(chalk.cyan.bold('📊 Recent System Events')); console.log(chalk.gray('─'.repeat(80))); const events = this.getRecentEvents(count); for (const event of events) { const timestamp = new Date(event.timestamp).toLocaleTimeString(); const icon = this.getEventIcon(event.type); const color = this.getEventColor(event.level); console.log(chalk.gray(timestamp), icon, color(this.formatEventMessage(event))); } } private getEventIcon(type: string): string { const icons: Record<string, string> = { agent_spawned: '🤖', agent_terminated: '🔚', task_assigned: '📌', task_completed: '✅', task_failed: '❌', system_error: 'âš ī¸', process_started: 'â–ļī¸', process_stopped: 'âšī¸', process_error: '🚨', }; return icons[type] || 'â€ĸ'; } private getEventColor(level: string): (text: string) => string { switch (level) { case 'success': return chalk.green; case 'info': return chalk.blue; case 'warning': return chalk.yellow; case 'error': return chalk.red; default: return chalk.white; } } private formatEventMessage(event: any): string { switch (event.type) { case 'agent_spawned': return `Agent spawned: ${event.data.agentId} (${event.data.profile?.type || 'unknown'})`; case 'agent_terminated': return `Agent terminated: ${event.data.agentId} - ${event.data.reason}`; case 'task_assigned': return `Task ${event.data.taskId} assigned to ${event.data.agentId}`; case 'task_completed': return `Task completed: ${event.data.taskId}`; case 'task_failed': return `Task failed: ${event.data.taskId} - ${event.data.error?.message}`; case 'system_error': return `System error in ${event.data.component}: ${event.data.error?.message}`; case 'process_started': return `Process started: ${event.data.processName}`; case 'process_stopped': return `Process stopped: ${event.data.processId}`; case 'process_error': return `Process error: ${event.data.processId} - ${event.data.error}`; default: return JSON.stringify(event.data); } } printSystemHealth(): void { const stats = this.processManager.getSystemStats(); const processes = this.processManager.getAllProcesses(); console.log(chalk.cyan.bold('đŸĨ System Health')); console.log(chalk.gray('─'.repeat(60))); // Overall status const healthStatus = stats.errorProcesses === 0 ? chalk.green('● Healthy') : chalk.red(`● Unhealthy (${stats.errorProcesses} errors)`); console.log('Status:', healthStatus); console.log('Uptime:', this.formatUptime(stats.systemUptime)); console.log(); // Process status console.log(chalk.white.bold('Process Status:')); for (const process of processes) { const status = this.getProcessStatusIcon(process.status); const metrics = process.metrics; let line = ` ${status} ${process.name.padEnd(20)}`; if (metrics && process.status === 'running') { line += chalk.gray(` CPU: ${metrics.cpu?.toFixed(1)}% `); line += chalk.gray(` MEM: ${metrics.memory?.toFixed(0)}MB`); } console.log(line); } console.log(); // System metrics console.log(chalk.white.bold('System Metrics:')); console.log(` Active Processes: ${stats.runningProcesses}/${stats.totalProcesses}`); console.log(` Recent Events: ${this.events.length}`); // Recent errors const recentErrors = this.events.filter((e) => e.level === 'error').slice(0, 3); if (recentErrors.length > 0) { console.log(); console.log(chalk.red.bold('Recent Errors:')); for (const error of recentErrors) { const time = new Date(error.timestamp).toLocaleTimeString(); console.log(chalk.red(` ${time} - ${this.formatEventMessage(error)}`)); } } } private getProcessStatusIcon(status: string): string { switch (status) { case 'running': return chalk.green('●'); case 'stopped': return chalk.gray('○'); case 'starting': return chalk.yellow('◐'); case 'stopping': return chalk.yellow('◑'); case 'error': return chalk.red('✗'); default: return chalk.gray('?'); } } private formatUptime(ms: number): string { const seconds = Math.floor(ms / 1000); const minutes = Math.floor(seconds / 60); const hours = Math.floor(minutes / 60); const days = Math.floor(hours / 24); if (days > 0) { return `${days}d ${hours % 24}h ${minutes % 60}m`; } else if (hours > 0) { return `${hours}h ${minutes % 60}m ${seconds % 60}s`; } else if (minutes > 0) { return `${minutes}m ${seconds % 60}s`; } else { return `${seconds}s`; } } }