$series */ private function trend(array $series, string $suffix = '%'): array { $cur = (int) (end($series) ?: 0); $prev = (int) ($series[max(0, count($series) - 8)] ?? $cur); $d = $cur - $prev; return [ 'dir' => $d > 1 ? 'up' : ($d < -1 ? 'down' : 'flat'), 'text' => ($d >= 0 ? '+' : '').$d.$suffix, ]; } /** Live metrics for the active server (briefly cached), DB values as fallback. */ private function liveMetrics(FleetService $fleet, ?Server $active): array { $fallback = [ 'cpu' => (int) ($active?->cpu ?? 0), 'mem' => (int) ($active?->mem ?? 0), 'disk' => (int) ($active?->disk ?? 0), 'load' => 0.0, ]; if (! $active || ! $active->credential_exists) { return $fallback; } try { return Cache::remember("metrics:{$active->id}", 10, fn () => $fleet->metrics($active)); } catch (Throwable) { return $fallback; } } /** A handful of notable systemd units (failed + running first). */ private function liveServices(FleetService $fleet, ?Server $active): array { if (! $active || ! $active->credential_exists) { return []; } try { $svc = Cache::remember("svc:{$active->id}", 15, fn () => $fleet->systemd($active, 1)['services']); } catch (Throwable) { return []; } $rank = fn (array $s): int => match ($s['sub']) { 'failed' => 0, 'running' => 1, default => 2, }; usort($svc, fn ($a, $b) => [$rank($a), $a['name']] <=> [$rank($b), $b['name']]); return array_slice($svc, 0, 8); } public function render(FleetService $fleet) { $active = $this->activeServer(); $m = $this->liveMetrics($fleet, $active); $cpu = $m['cpu']; $mem = $m['mem']; $disk = $m['disk']; $cpuSeries = $this->series(max(8, $cpu), 40, 10); $memSeries = $this->series(max(8, $mem), 40, 7); $diskSeries = $this->series(max(4, $disk), 40, 2); $loadSeries = $this->series(max(8, (int) round($cpu * 0.8)), 40, 12); return view('livewire.dashboard', [ 'active' => $active, 'cpu' => $cpu, 'mem' => $mem, 'disk' => $disk, 'load' => round($m['load'], 2), 'cpuSeries' => $cpuSeries, 'memSeries' => $memSeries, 'diskSeries' => $diskSeries, 'loadSeries' => $loadSeries, 'cpuTrend' => $this->trend($cpuSeries), 'memTrend' => $this->trend($memSeries), 'diskTrend' => $this->trend($diskSeries), 'loadTrend' => $this->trend($loadSeries, ''), 'services' => $this->liveServices($fleet, $active), 'events' => AuditEvent::with('server')->latest()->limit(6)->get(), ]); } }