option('json'); $this->option('details'); $health = $this->performHealthCheck($emuService, $nitroService); if ($json) { $this->line(json_encode($health, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); return $health['status'] === 'healthy' ? 0 : 1; } $this->displayHealthCheck($health); return $health['status'] === 'healthy' ? 0 : 1; } private function performHealthCheck(EmulatorUpdateService $emuService, NitroUpdateService $nitroService): array { $checks = []; $issues = []; $warnings = []; $checks['timestamp'] = now()->toIso8601String(); $checks['php'] = [ 'version' => PHP_VERSION, 'status' => 'ok', ]; $checks['system'] = [ 'os' => PHP_OS, 'user' => posix_getpwuid(posix_geteuid())['name'] ?? 'unknown', ]; $diskFree = @disk_free_space('/'); $diskTotal = @disk_total_space('/'); $diskPercent = $diskTotal > 0 ? round(($diskFree / $diskTotal) * 100, 1) : 0; $checks['disk'] = [ 'free' => $this->formatBytes($diskFree), 'total' => $this->formatBytes($diskTotal), 'percent_free' => $diskPercent, 'status' => $diskPercent > 10 ? 'ok' : 'critical', ]; if ($diskPercent < 10) { $issues[] = 'Disk space critically low: ' . $diskPercent . '% free'; } elseif ($diskPercent < 20) { $warnings[] = 'Disk space low: ' . $diskPercent . '% free'; } try { $emuDiagnosis = $emuService->diagnose(); $checks['emulator'] = [ 'configured' => $emuDiagnosis['checks']['is_configured'] ?? false, 'jar_exists' => $emuDiagnosis['checks']['jar_exists'] ?? false, 'service_running' => $emuDiagnosis['checks']['service_running'] ?? false, 'db_connected' => $emuDiagnosis['checks']['emulator_db_connected'] ?? false, 'status' => empty($emuDiagnosis['issues']) ? 'ok' : 'issues', 'issues' => $emuDiagnosis['issues'] ?? [], ]; if (! empty($emuDiagnosis['issues'])) { foreach ($emuDiagnosis['issues'] as $issue) { $issues[] = 'Emulator: ' . $issue; } } } catch (\Exception $e) { $checks['emulator'] = [ 'status' => 'error', 'error' => $e->getMessage(), ]; $issues[] = 'Emulator check failed: ' . $e->getMessage(); } try { $nitroDiagnosis = $nitroService->diagnose(); $checks['nitro'] = [ 'client_installed' => $nitroDiagnosis['checks']['client_installed'] ?? false, 'renderer_installed' => $nitroDiagnosis['checks']['renderer_installed'] ?? false, 'deployed' => $nitroDiagnosis['checks']['deployed'] ?? false, 'status' => empty($nitroDiagnosis['issues']) ? 'ok' : 'issues', 'issues' => $nitroDiagnosis['issues'] ?? [], ]; if (! empty($nitroDiagnosis['issues'])) { foreach ($nitroDiagnosis['issues'] as $issue) { $issues[] = 'Nitro: ' . $issue; } } } catch (\Exception $e) { $checks['nitro'] = [ 'status' => 'error', 'error' => $e->getMessage(), ]; $issues[] = 'Nitro check failed: ' . $e->getMessage(); } try { $sqlDiagnosis = $emuService->diagnoseSqlUpdates(); $checks['sql_updates'] = [ 'table_exists' => $sqlDiagnosis['table_exists'] ?? false, 'applied' => $sqlDiagnosis['applied_count'] ?? 0, 'pending' => $sqlDiagnosis['pending_count'] ?? 0, 'status' => ($sqlDiagnosis['pending_count'] ?? 0) > 0 ? 'pending' : 'ok', ]; if (($sqlDiagnosis['pending_count'] ?? 0) > 0) { $warnings[] = $sqlDiagnosis['pending_count'] . ' SQL updates pending'; } } catch (\Exception $e) { $checks['sql_updates'] = [ 'status' => 'error', 'error' => $e->getMessage(), ]; } $webserverCheck = Process::timeout(5)->run('which nginx || which apache2 || which httpd'); $checks['webserver'] = [ 'installed' => $webserverCheck->successful(), 'status' => $webserverCheck->successful() ? 'ok' : 'unknown', ]; $mysqlCheck = Process::timeout(5)->run('which mysql || which mariadb'); $checks['database'] = [ 'client_installed' => $mysqlCheck->successful(), 'status' => $mysqlCheck->successful() ? 'ok' : 'unknown', ]; $nodeCheck = Process::timeout(5)->run('which node && which yarn'); $checks['node'] = [ 'installed' => $nodeCheck->successful(), 'status' => $nodeCheck->successful() ? 'ok' : 'missing', ]; if (! $nodeCheck->successful()) { $warnings[] = 'Node.js/Yarn niet geïnstalleerd'; } $status = $issues === [] ? 'healthy' : ($warnings === [] ? 'warning' : 'degraded'); return [ 'status' => $status, 'checks' => $checks, 'issues' => $issues, 'warnings' => $warnings, ]; } private function displayHealthCheck(array $health): void { $status = $health['status']; $statusIcon = match ($status) { 'healthy' => '✅', 'warning' => '⚠️', 'degraded' => '❌', default => '❓', }; $this->info("{$statusIcon} Systeem Gezondheid: " . strtoupper($status)); $this->line('═══════════════════════════════════════════════'); $checks = $health['checks'] ?? []; $this->line('📦 Systeem:'); $this->line(' PHP: ' . ($checks['php']['version'] ?? '?')); $this->line(' User: ' . ($checks['system']['user'] ?? '?')); $diskStatus = $checks['disk']['status'] ?? '?'; $diskIcon = $diskStatus === 'ok' ? '✅' : '❌'; $this->line(" {$diskIcon} Disk: " . ($checks['disk']['percent_free'] ?? '?') . '% vrij'); $emuStatus = $checks['emulator']['status'] ?? '?'; $emuIcon = $emuStatus === 'ok' ? '✅' : '⚠️'; $this->line(" {$emuIcon} Emulator: " . ucfirst($emuStatus)); $nitroStatus = $checks['nitro']['status'] ?? '?'; $nitroIcon = $nitroStatus === 'ok' ? '✅' : '⚠️'; $this->line(" {$nitroIcon} Nitro: " . ucfirst($nitroStatus)); $sqlStatus = $checks['sql_updates']['status'] ?? '?'; $sqlIcon = $sqlStatus === 'ok' ? '✅' : '⚠️'; $this->line(" {$sqlIcon} SQL Updates: " . ucfirst($sqlStatus) . ' (' . ($checks['sql_updates']['applied'] ?? 0) . ' toegepast)'); $nodeStatus = $checks['node']['status'] ?? '?'; $nodeIcon = $nodeStatus === 'ok' ? '✅' : '❌'; $this->line(" {$nodeIcon} Node.js: " . ucfirst($nodeStatus)); if (! empty($health['issues'])) { $this->line(''); $this->error('❌ Problemen:'); foreach ($health['issues'] as $issue) { $this->line(' - ' . $issue); } } if (! empty($health['warnings'])) { $this->line(''); $this->warn('⚠️ Waarschuwingen:'); foreach ($health['warnings'] as $warning) { $this->line(' - ' . $warning); } } $this->line('═══════════════════════════════════════════════'); if ($status === 'healthy') { $this->info('✅ Alles werkt correct!'); } else { $this->warn('Run "php artisan system:repair" om problemen op te lossen'); } } private function formatBytes(?float $bytes): string { if ($bytes === null) { return 'N/A'; } $units = ['B', 'KB', 'MB', 'GB', 'TB']; $i = 0; while ($bytes >= 1024 && $i < count($units) - 1) { $bytes /= 1024; $i++; } return round($bytes, 2) . ' ' . $units[$i]; } }