You've already forked Atomcms-edit
252 lines
9.0 KiB
PHP
Executable File
252 lines
9.0 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Services\EmulatorUpdateService;
|
|
use App\Services\NitroUpdateService;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Process;
|
|
|
|
class SystemHealthCommand extends Command
|
|
{
|
|
#[\Override]
|
|
protected $signature = 'system:health
|
|
{--json : Output als JSON}
|
|
{--details : Toon meer details}';
|
|
|
|
#[\Override]
|
|
protected $description = 'Controleer systeem gezondheid';
|
|
|
|
public function handle(EmulatorUpdateService $emuService, NitroUpdateService $nitroService): int
|
|
{
|
|
$json = $this->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];
|
|
}
|
|
}
|