*/ public array $services = []; public ?string $checkedAt = null; public function mount(): void { $this->refreshHealth(); } /** Re-run all service health probes (called on mount, wire:poll and the refresh button). */ public function refreshHealth(): void { $this->services = [ $this->checkDatabase(), $this->checkRedis(), $this->checkReverb(), $this->checkHorizon(), ]; $this->checkedAt = now()->format('H:i:s'); } /** Worst state across services (drives the banner): offline > warning > online. */ public function worstState(): string { $states = array_column($this->services, 'state'); return in_array('offline', $states, true) ? 'offline' : (in_array('warning', $states, true) ? 'warning' : 'online'); } public function problemCount(): int { return count(array_filter($this->services, fn ($s) => $s['state'] !== 'online')); } protected function checkDatabase(): array { $base = ['key' => 'database', 'label' => __('dashboard.svc_database'), 'icon' => 'network']; try { $start = microtime(true); DB::connection()->select('select 1'); $ms = (int) round((microtime(true) - $start) * 1000); return $base + ['state' => 'online', 'detail' => $ms.' ms']; } catch (\Throwable) { return $base + ['state' => 'offline', 'detail' => __('dashboard.svc_unreachable')]; } } protected function checkRedis(): array { $base = ['key' => 'cache', 'label' => __('dashboard.svc_cache'), 'icon' => 'devices']; try { $start = microtime(true); Redis::connection()->ping(); $ms = (int) round((microtime(true) - $start) * 1000); return $base + ['state' => 'online', 'detail' => $ms.' ms']; } catch (\Throwable) { return $base + ['state' => 'offline', 'detail' => __('dashboard.svc_unreachable')]; } } protected function checkReverb(): array { $base = ['key' => 'realtime', 'label' => __('dashboard.svc_realtime'), 'icon' => 'activity']; $host = config('broadcasting.connections.reverb.options.host', 'reverb'); $port = (int) config('broadcasting.connections.reverb.options.port', 8080); $conn = @fsockopen($host, $port, $errno, $errstr, 1.0); if ($conn) { fclose($conn); return $base + ['state' => 'online', 'detail' => $host.':'.$port]; } return $base + ['state' => 'offline', 'detail' => __('dashboard.svc_unreachable')]; } protected function checkHorizon(): array { $base = ['key' => 'queue', 'label' => __('dashboard.svc_queue'), 'icon' => 'automation']; try { $masters = app(\Laravel\Horizon\Contracts\MasterSupervisorRepository::class)->all(); if (empty($masters)) { return $base + ['state' => 'offline', 'detail' => __('dashboard.svc_stopped')]; } $running = collect($masters)->contains(fn ($m) => ($m->status ?? null) === 'running'); return $base + ($running ? ['state' => 'online', 'detail' => __('dashboard.svc_running')] : ['state' => 'warning', 'detail' => __('dashboard.svc_stopped')]); } catch (\Throwable) { return $base + ['state' => 'offline', 'detail' => __('dashboard.svc_unreachable')]; } } public function render() { return view('livewire.dashboard'); } }