option('node'); if ($nodeId) { return $this->checkSingleNode($monitoringService, (int) $nodeId); } return $this->checkAllNodes($monitoringService); } private function checkSingleNode(NodeMonitoringService $monitoringService, int $nodeId): int { $node = HostingNode::find($nodeId); if (!$node) { $this->error("Node with ID {$nodeId} not found."); return self::FAILURE; } $this->info("Checking node: {$node->name} ({$node->ip_address})..."); $result = $monitoringService->checkNode($node); $this->displayNodeResult($node, $result); return self::SUCCESS; } private function checkAllNodes(NodeMonitoringService $monitoringService): int { $nodes = HostingNode::whereIn('status', [ HostingNode::STATUS_ACTIVE, HostingNode::STATUS_FULL, HostingNode::STATUS_MAINTENANCE, ])->get(); if ($nodes->isEmpty()) { $this->warn('No active nodes found to check.'); return self::SUCCESS; } $this->info("Checking {$nodes->count()} node(s)..."); $this->newLine(); $results = []; $bar = $this->output->createProgressBar($nodes->count()); $bar->start(); foreach ($nodes as $node) { $results[$node->id] = $monitoringService->checkNode($node); $bar->advance(); } $bar->finish(); $this->newLine(2); $this->displaySummaryTable($nodes, $results); $unhealthy = collect($results)->filter(fn($r) => ($r['health'] ?? '') !== NodeMonitoringService::HEALTH_OK); if ($unhealthy->isNotEmpty()) { $this->newLine(); $this->warn("⚠️ {$unhealthy->count()} node(s) require attention."); } return self::SUCCESS; } private function displayNodeResult(HostingNode $node, array $result): void { $health = $result['health'] ?? 'unknown'; $healthIcon = match ($health) { NodeMonitoringService::HEALTH_OK => '✅', NodeMonitoringService::HEALTH_WARNING => '⚠️', NodeMonitoringService::HEALTH_CRITICAL => '🔴', NodeMonitoringService::HEALTH_UNREACHABLE => '❌', default => '❓', }; $this->newLine(); $this->info("{$healthIcon} Health: " . strtoupper($health)); $this->newLine(); if (isset($result['error'])) { $this->error("Error: {$result['error']}"); return; } $this->table( ['Metric', 'Value'], [ ['CPU Usage', ($result['cpu']['usage_percent'] ?? 'N/A') . '%'], ['RAM Usage', ($result['memory']['usage_percent'] ?? 'N/A') . '%'], ['Disk Usage (root)', ($result['disk']['root']['usage_percent'] ?? 'N/A') . '%'], ['Load (1m)', $result['load']['load_1'] ?? 'N/A'], ['Load per Core', $result['load']['load_per_core'] ?? 'N/A'], ['Uptime', $result['uptime']['formatted'] ?? 'N/A'], ['Processes', $result['processes']['total'] ?? 'N/A'], ['Response Time', ($result['response_time_ms'] ?? 'N/A') . 'ms'], ] ); if (!empty($result['services'])) { $this->newLine(); $this->info('Services:'); foreach ($result['services'] as $service => $running) { $icon = $running ? '✅' : '❌'; $this->line(" {$icon} {$service}"); } } } private function displaySummaryTable($nodes, array $results): void { $rows = []; foreach ($nodes as $node) { $result = $results[$node->id] ?? []; $health = $result['health'] ?? 'unknown'; $healthIcon = match ($health) { NodeMonitoringService::HEALTH_OK => '✅', NodeMonitoringService::HEALTH_WARNING => '⚠️', NodeMonitoringService::HEALTH_CRITICAL => '🔴', NodeMonitoringService::HEALTH_UNREACHABLE => '❌', default => '❓', }; $rows[] = [ $node->name, $node->ip_address, "{$healthIcon} " . strtoupper($health), isset($result['cpu']['usage_percent']) ? $result['cpu']['usage_percent'] . '%' : 'N/A', isset($result['memory']['usage_percent']) ? $result['memory']['usage_percent'] . '%' : 'N/A', isset($result['disk']['root']['usage_percent']) ? $result['disk']['root']['usage_percent'] . '%' : 'N/A', $result['load']['load_1'] ?? 'N/A', "{$node->current_accounts}/{$node->max_accounts}", ]; } $this->table( ['Node', 'IP', 'Health', 'CPU', 'RAM', 'Disk', 'Load', 'Accounts'], $rows ); } }