mailwolt/app/Livewire/Ui/Dashboard/HealthCard.php

352 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
//
//namespace App\Livewire\Ui\Dashboard;
//
//use Carbon\Carbon;
//use Illuminate\Support\Facades\Cache;
//use Livewire\Component;
//
//class HealthCard extends Component
//{
// // Rohdaten
// public array $services = [];
// public array $meta = [];
//
// // UI: Balken/Segmente
// public int $barSegments = 24;
// public array $cpuSeg = [];
// public array $ramSeg = [];
//
// // UI: Load & Uptime
// public string $loadBadgeText = '';
// public array $loadDots = [];
// public array $uptimeChips = [];
// public string $uptimeIcon = 'ph ph-clock';
//
// // UI: Services kompakt
// public array $servicesCompact = [];
//
// // Storage
// public ?int $diskUsedGb = null;
// public ?int $diskTotalGb = null;
// public ?int $diskPercent = null;
// public ?int $diskFreeGb = null;
// public array $diskSegments = [];
// public int $diskInnerSize = 160; // grauer Kreis
// public int $diskSegOuterRadius = 92; // Abstand der Ticks
// public array $diskCenterText = ['percent'=>'%','label'=>'Speicher belegt'];
//
// // Anzeige oben
// public ?string $ramSummary = null;
// public ?string $loadText = null;
// public ?string $uptimeText = null;
// public ?int $cpuPercent = null;
// public ?int $ramPercent = null;
// public ?string $updatedAtHuman = null;
//
// public $guardOk = [];
// public function mount(): void
// {
// $this->loadData();
// }
//
// public function loadData(): void
// {
// $this->services = Cache::get('health:services', []);
// $this->meta = Cache::get('health:meta', []);
//
// $this->hydrateSystem();
// $this->hydrateDisk();
// $this->hydrateUpdatedAt();
// $this->decorateServicesCompact();
// $this->decorateDisk();
// }
//
// public function render()
// {
// return view('livewire.ui.dashboard.health-card');
// }
//
// /* ---------------- Aufbereitung ---------------- */
//
// protected function hydrateSystem(): void
// {
// $sys = is_array($this->meta['system'] ?? null) ? $this->meta['system'] : [];
//
// // RAM %
// $this->ramPercent = $this->numInt($this->pick($sys, ['ram','ram_percent','mem_percent','memory']));
// if ($this->ramPercent === null && is_array($sys['ram'] ?? null)) {
// $this->ramPercent = $this->numInt($this->pick($sys['ram'], ['percent','used_percent']));
// }
//
// // RAM Summary "used / total"
// $used = $this->numInt($this->pick($sys['ram'] ?? [], ['used_gb','used','usedGB']));
// $tot = $this->numInt($this->pick($sys['ram'] ?? [], ['total_gb','total','totalGB']));
// $this->ramSummary = ($used !== null && $tot !== null) ? "{$used} GB / {$tot} GB" : null;
//
// // Load (1/5/15)
// $load1 = $this->numFloat($this->pick($sys, ['cpu_load_1','load1','load_1']));
// $load5 = $this->numFloat($this->pick($sys, ['cpu_load_5','load5','load_5']));
// $load15 = $this->numFloat($this->pick($sys, ['cpu_load_15','load15','load_15']));
//
// $loadMixed = $this->pick($sys, ['load','loadavg','load_avg','load_text']);
// if (is_array($loadMixed)) {
// $vals = array_values($loadMixed);
// $load1 ??= $this->numFloat($vals[0] ?? null);
// $load5 ??= $this->numFloat($vals[1] ?? null);
// $load15 ??= $this->numFloat($vals[2] ?? null);
// }
// $this->loadText = $this->fmtLoad($load1, $load5, $load15, is_string($loadMixed) ? $loadMixed : null);
//
// // CPU %
// $this->cpuPercent = $this->numInt($this->pick($sys, ['cpu','cpu_percent','cpuUsage','cpu_usage']));
// if ($this->cpuPercent === null && $load1 !== null) {
// $cores = $this->numInt($this->pick($sys, ['cores','cpu_cores','num_cores'])) ?: 1;
// $this->cpuPercent = (int) round(min(100, max(0, ($load1 / max(1,$cores)) * 100)));
// }
//
// // Uptime
// $this->uptimeText = $this->pick($sys, ['uptime_human','uptimeText','uptime']);
// if (!$this->uptimeText) {
// $uptimeSec = $this->numInt($this->pick($sys, ['uptime_seconds','uptime_sec','uptime_s']));
// if ($uptimeSec !== null) $this->uptimeText = $this->secondsToHuman($uptimeSec);
// }
//
// // Segment-Balken
// $this->cpuSeg = $this->buildSegments($this->cpuPercent);
// $this->ramSeg = $this->buildSegments($this->ramPercent);
//
// // Load: Dots (1/5/15 relativ zu Kernen)
// $cores = max(1, (int)($this->pick($sys, ['cores','cpu_cores','num_cores']) ?? 1));
// $ratio1 = $load1 !== null ? $load1 / $cores : null;
// $ratio5 = $load5 !== null ? $load5 / $cores : null;
// $ratio15 = $load15 !== null ? $load15 / $cores : null;
//
// $this->loadBadgeText = $this->loadText ?? '';
// $this->loadDots = [
// ['label'=>'1m', 'cls'=>$this->loadDotClass($ratio1)],
// ['label'=>'5m', 'cls'=>$this->loadDotClass($ratio5)],
// ['label'=>'15m', 'cls'=>$this->loadDotClass($ratio15)],
// ];
//
// // Uptime Chips
// $chips = [];
// if ($this->uptimeText) {
// $d = $h = $m = null;
// if (preg_match('/(\d+)d/i', $this->uptimeText, $m1)) $d = (int)$m1[1];
// if (preg_match('/(\d+)h/i', $this->uptimeText, $m2)) $h = (int)$m2[1];
// if (preg_match('/(\d+)m/i', $this->uptimeText, $m3)) $m = (int)$m3[1];
// if ($d !== null) $chips[] = ['v'=>$d, 'u'=>'Tage'];
// if ($h !== null) $chips[] = ['v'=>$h, 'u'=>'Stunden'];
// if ($m !== null) $chips[] = ['v'=>$m, 'u'=>'Minuten'];
// }
// $this->uptimeChips = $chips ?: [['v'=>'','u'=>'']];
// }
//
// protected function hydrateDisk(): void
// {
// $disk = is_array($this->meta['disk'] ?? null) ? $this->meta['disk'] : [];
//
// $this->diskPercent = $this->numInt($this->pick($disk, ['percent','usage']));
// $this->diskFreeGb = $this->numInt($this->pick($disk, ['free_gb','free']));
//
// // total/used berechnen, falls nicht geliefert
// if ($this->diskFreeGb !== null && $this->diskPercent !== null && $this->diskPercent < 100) {
// $p = max(0, min(100, $this->diskPercent)) / 100;
// $estTotal = (int) round($this->diskFreeGb / (1 - $p));
// $this->diskTotalGb = $estTotal > 0 ? $estTotal : null;
// }
// if ($this->diskTotalGb !== null && $this->diskFreeGb !== null) {
// $u = $this->diskTotalGb - $this->diskFreeGb;
// $this->diskUsedGb = $u >= 0 ? $u : null;
// }
// }
//
// protected function hydrateUpdatedAt(): void
// {
// $updated = $this->meta['updated_at'] ?? null;
// try { $this->updatedAtHuman = $updated ? Carbon::parse($updated)->diffForHumans() : '';
// } catch (\Throwable) { $this->updatedAtHuman = ''; }
// }
//
// protected function decorateServicesCompact(): void
// {
// $nameMap = [
// 'postfix' => ['label' => 'Postfix', 'hint' => 'MTA'],
// 'dovecot' => ['label' => 'Dovecot', 'hint' => 'IMAP/POP3'],
// 'rspamd' => ['label' => 'Rspamd', 'hint' => 'Spamfilter'],
// 'db' => ['label' => 'Datenbank', 'hint' => 'MySQL/MariaDB'],
// '127.0.0.1:6379' => ['label' => 'Redis', 'hint' => 'Cache/Queue'],
// '127.0.0.1:8080' => ['label' => 'Reverb', 'hint' => 'WebSocket'],
// ];
//
//// $nameMap = [
//// // --- Mail ---
//// 'postfix' => ['label' => 'Postfix', 'hint' => 'MTA / Versand'],
//// 'dovecot' => ['label' => 'Dovecot', 'hint' => 'IMAP / POP3'],
//// 'rspamd' => ['label' => 'Rspamd', 'hint' => 'Spamfilter'],
//// 'clamav' => ['label' => 'ClamAV', 'hint' => 'Virenscanner'],
////
//// // --- Daten & Cache ---
//// 'db' => ['label' => 'Datenbank', 'hint' => 'MySQL / MariaDB'],
//// '127.0.0.1:6379' => ['label' => 'Redis', 'hint' => 'Cache / Queue'],
////
//// // --- Web / PHP ---
//// 'php8.2-fpm' => ['label' => 'PHP-FPM', 'hint' => 'PHP Runtime'],
//// 'nginx' => ['label' => 'Nginx', 'hint' => 'Webserver'],
////
//// // --- MailWolt spezifisch ---
//// 'mailwolt-queue' => ['label' => 'MailWolt Queue', 'hint' => 'Job Worker'],
//// 'mailwolt-schedule'=> ['label' => 'MailWolt Schedule','hint' => 'Task Scheduler'],
////
//// // --- Sonstige Infrastruktur ---
//// 'fail2ban' => ['label' => 'Fail2Ban', 'hint' => 'SSH / Mail Protection'],
//// 'systemd-journald'=> ['label' => 'System Logs', 'hint' => 'Logging / Journal'],
////
//// // --- WebSocket & Echtzeit ---
//// '127.0.0.1:8080' => ['label' => 'Reverb', 'hint' => 'WebSocket Server'],
//// ];
//
// $existing = collect($this->services)->keyBy('name');
//
// $this->servicesCompact = collect($nameMap)
// ->map(function ($meta, $key) use ($existing) {
// $srv = $existing->get($key, []);
// $ok = (bool)($srv['ok'] ?? false);
//
// return [
// 'label' => $meta['label'],
// 'hint' => $meta['hint'],
// 'ok' => $ok,
//
// // Punktfarbe
// 'dotClass' => $ok ? 'bg-emerald-400' : 'bg-rose-400',
//
// // ✅ Bessere Status-Texte
// 'pillText' => $ok ? 'Aktiv' : 'Offline',
//
// // Farbe für Pill
// 'pillClass' => $ok
// ? 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10'
// : 'text-rose-300 border-rose-400/30 bg-rose-500/10',
// ];
// })
// ->values()
// ->all();
//
// $this->guardOk = collect($this->services)->every(
// fn($s) => (bool)($s['ok'] ?? false)
// );
//// $this->servicesCompact = collect($this->services)
//// ->map(function ($srv) use ($nameMap) {
//// $key = (string)($srv['name'] ?? '');
//// $ok = (bool) ($srv['ok'] ?? false);
//// $label = $nameMap[$key]['label'] ?? ucfirst($key);
//// $hint = $nameMap[$key]['hint'] ?? (str_contains($key, ':') ? $key : '');
////
//// var_dump($srv);
//// return [
//// 'label' => $label,
//// 'hint' => $hint,
//// 'ok' => $ok,
//// 'dotClass' => $ok ? 'bg-emerald-400' : 'bg-rose-400',
//// 'pillText' => $ok ? 'Läuft' : 'Down',
//// 'pillClass' => $ok
//// ? 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10'
//// : 'text-rose-300 border-rose-400/30 bg-rose-500/10',
//// ];
//// })
//// ->values()
//// ->all();
// }
//
// protected function decorateDisk(): void
// {
// $percent = (int) max(0, min(100, (int)($this->diskPercent ?? 0)));
// $this->diskCenterText = [
// 'percent' => is_numeric($this->diskPercent) ? $this->diskPercent.'%' : '%',
// 'label' => 'Speicher belegt',
// ];
//
// $count = 48;
// $activeN = is_numeric($this->diskPercent) ? (int) round($count * $percent / 100) : 0;
// $step = 360 / $count;
//
// $activeClass = match (true) {
// $percent >= 90 => 'bg-rose-400',
// $percent >= 70 => 'bg-amber-300',
// default => 'bg-emerald-400',
// };
//
// $this->diskSegments = [];
// for ($i = 0; $i < $count; $i++) {
// $angle = ($i * $step) - 90; // Start bei 12 Uhr
// $this->diskSegments[] = [
// 'angle' => $angle,
// 'class' => $i < $activeN ? $activeClass : 'bg-white/16',
// ];
// }
// }
//
// /* ---------------- Helpers ---------------- */
//
// protected function pick(array $arr, array $keys)
// {
// foreach ($keys as $k) {
// if (array_key_exists($k, $arr) && $arr[$k] !== null && $arr[$k] !== '') {
// return $arr[$k];
// }
// }
// return null;
// }
//
// protected function numInt($v): ?int { return is_numeric($v) ? (int) round($v) : null; }
// protected function numFloat($v): ?float{ return is_numeric($v) ? (float)$v : null; }
//
// protected function fmtLoad(?float $l1, ?float $l5, ?float $l15, ?string $fallback): ?string
// {
// if ($l1 !== null || $l5 !== null || $l15 !== null) {
// $fmt = fn($x) => $x === null ? '' : number_format($x, 2);
// return "{$fmt($l1)} / {$fmt($l5)} / {$fmt($l15)}";
// }
// return $fallback ?: null;
// }
//
// protected function secondsToHuman(int $s): string
// {
// $d = intdiv($s, 86400); $s %= 86400;
// $h = intdiv($s, 3600); $s %= 3600;
// $m = intdiv($s, 60);
// if ($d > 0) return "{$d}d {$h}h";
// if ($h > 0) return "{$h}h {$m}m";
// return "{$m}m";
// }
//
// protected function toneByPercent(?int $p): string {
// if ($p === null) return 'white';
// if ($p >= 90) return 'rose';
// if ($p >= 70) return 'amber';
// return 'emerald';
// }
//
// protected function buildSegments(?int $percent): array {
// $n = max(6, $this->barSegments);
// $filled = is_numeric($percent) ? (int) round($n * max(0, min(100, $percent)) / 100) : 0;
// $tone = $this->toneByPercent($percent);
// $fillCls = match($tone) {
// 'rose' => 'bg-rose-500/80',
// 'amber' => 'bg-amber-400/80',
// 'emerald'=> 'bg-emerald-500/80',
// default => 'bg-white/20',
// };
// return array_map(fn($i) => $i < $filled ? $fillCls : 'bg-white/10', range(0, $n-1));
// }
//
// protected function loadDotClass(?float $ratio): string {
// if ($ratio === null) return 'bg-white/25';
// if ($ratio >= 0.9) return 'bg-rose-500';
// if ($ratio >= 0.7) return 'bg-amber-400';
// return 'bg-emerald-400';
// }
//}