services = [ ['name' => 'nginx.service', 'status' => 'online', 'desc' => 'A high performance web server', 'cpu' => 1.4, 'mem' => 128], ['name' => 'mariadb.service', 'status' => 'online', 'desc' => 'MariaDB 11 database server', 'cpu' => 3.8, 'mem' => 612], ['name' => 'redis-server.service', 'status' => 'online', 'desc' => 'Advanced key-value store', 'cpu' => 0.6, 'mem' => 44], ['name' => 'php8.3-fpm.service', 'status' => 'warning', 'desc' => 'PHP 8.3 FastCGI Process Manager', 'cpu' => 6.1, 'mem' => 320], ['name' => 'fail2ban.service', 'status' => 'offline', 'desc' => 'Ban hosts with auth errors', 'cpu' => 0, 'mem' => 0], ]; } /** Deterministic wavy series around a base — seeds the sparklines/chart. */ private function series(float $base, int $n = 40, float $amp = 9): array { $out = []; for ($i = 0; $i < $n; $i++) { $v = $base + sin($i / 3.0) * $amp + sin($i / 6.5) * ($amp * 0.55) + cos($i / 2.0) * 2; $out[] = (int) max(2, min(98, round($v))); } return $out; } /** @param array $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, ]; } public function render() { $active = $this->activeServer(); $cpu = (int) ($active?->cpu ?? 0); $mem = (int) ($active?->mem ?? 0); $disk = (int) ($active?->disk ?? 0); $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($cpu / 100 * 3.2, 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, ''), 'events' => AuditEvent::with('server')->latest()->limit(6)->get(), ]); } }