diff --git a/app/Jobs/RunHealthChecks.php b/app/Jobs/RunHealthChecks.php index b3d61d8..1f87aa9 100644 --- a/app/Jobs/RunHealthChecks.php +++ b/app/Jobs/RunHealthChecks.php @@ -6,7 +6,6 @@ use App\Support\CacheVer; use App\Support\WoltGuard\Probes; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Queue\Queueable; -use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; diff --git a/app/Livewire/Ui/System/ServicesCard.php b/app/Livewire/Ui/System/ServicesCard.php index 7e3d09b..15157c0 100644 --- a/app/Livewire/Ui/System/ServicesCard.php +++ b/app/Livewire/Ui/System/ServicesCard.php @@ -4,6 +4,7 @@ namespace App\Livewire\Ui\System; use App\Support\CacheVer; use App\Support\WoltGuard\Probes; +use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use Livewire\Component; @@ -44,27 +45,35 @@ class ServicesCard extends Component public function load(): void { + // 1) Karten aus Config laden $cards = config('woltguard.cards', []); - $raw = Cache::get(CacheVer::k('health:services'), []); - - // einmaliger Fallback für ältere Deploys: - if (empty($raw)) { - $raw = Cache::get('health:services', []); + if (empty($cards)) { + // Config-Clear/-Cache synchron ausführen (kostet ~ms) + try { + Artisan::call('config:clear'); + Artisan::call('config:cache'); + } catch (\Throwable $e) { + // ignoriere – UI soll trotzdem laufen + } + $cards = config('woltguard.cards', []); } + // 2) Service-Status aus Cache (versionierter Key) + $key = \App\Support\CacheVer::k('health:services'); + $raw = Cache::get($key, []); + // Legacy-Key als Fallback + if (empty($raw)) $raw = Cache::get('health:services', []); + $cached = collect($raw)->keyBy('name'); - $rows = []; - $ok = 0; - $total = 0; + $rows = []; + $ok = 0; - foreach ($cards as $key => $card) { - $total++; - // 1) Cache-Hit? - $isOk = (bool) ($cached->get($key)['ok'] ?? false); + foreach ($cards as $name => $card) { + $isOk = (bool) ($cached->get($name)['ok'] ?? false); - // 2) Fallback probe (falls Cache leer/alt) + // 3) Wenn Cache leer → aktiv prüfen if ($cached->isEmpty()) { foreach ($card['sources'] as $src) { if ($this->check($src)) { $isOk = true; break; } @@ -74,14 +83,22 @@ class ServicesCard extends Component if ($isOk) $ok++; $rows[] = [ - 'label' => $card['label'], - 'hint' => $card['hint'], + 'name' => $name, // <— wichtig, damit der Cache keyBy('name') später klappt + 'label' => $card['label'] ?? $name, + 'hint' => $card['hint'] ?? null, 'ok' => $isOk, ]; } + // 4) Wenn wir aktiv geprüft haben (Cache war leer) → Cache auffüllen + if ($cached->isEmpty() && !empty($rows)) { + Cache::put($key, $rows, 600); // 10 Minuten + Cache::forget('health:services'); // Legacy aufräumen + } + + // 5) Kopfzahlen + UI-Daten $this->totalCount = count($rows); - $this->okCount = collect($rows)->where('ok', true)->count(); + $this->okCount = $ok; $this->guardOk = $this->totalCount > 0 && $this->okCount === $this->totalCount; [$this->badgeText, $this->badgeClass, $this->badgeIcon] = @@ -89,17 +106,78 @@ class ServicesCard extends Component ? ['alle Dienste OK', 'text-emerald-200 bg-emerald-500/10 border-emerald-400/30', 'ph ph-check-circle'] : ["{$this->okCount}/{$this->totalCount} aktiv", 'text-amber-200 bg-amber-500/10 border-amber-400/30', 'ph ph-warning']; - $this->servicesCompact = collect($rows)->map(fn($row) => [ - 'label' => $row['label'], - 'hint' => $row['hint'], - 'ok' => $row['ok'], - 'dotClass' => $row['ok'] ? 'bg-emerald-400' : 'bg-rose-400', - 'pillText' => $row['ok'] ? 'Online' : 'Offline', - 'pillClass' => $row['ok'] + $this->servicesCompact = collect($rows)->map(fn($r) => [ + 'label' => $r['label'], + 'hint' => $r['hint'], + 'ok' => $r['ok'], + 'dotClass' => $r['ok'] ? 'bg-emerald-400' : 'bg-rose-400', + 'pillText' => $r['ok'] ? 'Online' : 'Offline', + 'pillClass' => $r['ok'] ? 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10' : 'text-rose-300 border-rose-400/30 bg-rose-500/10', ])->all(); } + +// public function load(): void +// { +// $cards = config('woltguard.cards', []); +// +// $raw = Cache::get(CacheVer::k('health:services'), []); +// +// // einmaliger Fallback für ältere Deploys: +// if (empty($raw)) { +// $raw = Cache::get('health:services', []); +// } +// +// $cached = collect($raw)->keyBy('name'); +// +// $rows = []; +// $ok = 0; +// $total = 0; +// +// foreach ($cards as $key => $card) { +// $total++; +// // 1) Cache-Hit? +// $isOk = (bool) ($cached->get($key)['ok'] ?? false); +// +// // 2) Fallback probe (falls Cache leer/alt) +// if ($cached->isEmpty()) { +// foreach ($card['sources'] as $src) { +// if ($this->check($src)) { $isOk = true; break; } +// } +// } +// +// if ($isOk) $ok++; +// +// $rows[] = [ +// 'label' => $card['label'], +// 'hint' => $card['hint'], +// 'ok' => $isOk, +// ]; +// } +// +// $this->totalCount = count($rows); +// $this->okCount = collect($rows)->where('ok', true)->count(); +// $this->guardOk = $this->totalCount > 0 && $this->okCount === $this->totalCount; +// +// [$this->badgeText, $this->badgeClass, $this->badgeIcon] = +// $this->guardOk +// ? ['alle Dienste OK', 'text-emerald-200 bg-emerald-500/10 border-emerald-400/30', 'ph ph-check-circle'] +// : ["{$this->okCount}/{$this->totalCount} aktiv", 'text-amber-200 bg-amber-500/10 border-amber-400/30', 'ph ph-warning']; +// +// $this->servicesCompact = collect($rows)->map(fn($row) => [ +// 'label' => $row['label'], +// 'hint' => $row['hint'], +// 'ok' => $row['ok'], +// 'dotClass' => $row['ok'] ? 'bg-emerald-400' : 'bg-rose-400', +// 'pillText' => $row['ok'] ? 'Online' : 'Offline', +// 'pillClass' => $row['ok'] +// ? 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10' +// : 'text-rose-300 border-rose-400/30 bg-rose-500/10', +// ])->all(); +// } + + // public function load(): void // { // // Cache nur als optionaler Beschleuniger für Einzel-Checks, diff --git a/config/mailwolt.php b/config/mailwolt.php index dfd3699..67ad3c7 100644 --- a/config/mailwolt.php +++ b/config/mailwolt.php @@ -3,7 +3,7 @@ return [ 'units' => [ ['name' => 'nginx', 'action' => 'reload'], - ['name' => 'php8.2-fpm', 'action' => 'restart'], +// ['name' => 'php8.2-fpm', 'action' => 'restart'], ['name' => 'postfix', 'action' => 'try-reload-or-restart'], ['name' => 'dovecot', 'action' => 'try-reload-or-restart'], ['name' => 'rspamd', 'action' => 'try-reload-or-restart'],