parent
cdb16fc4a5
commit
4aea5238ca
|
|
@ -0,0 +1,9 @@
|
||||||
|
[90m= [39m[34;4mApp\Models\Setting[39;24m {#6409
|
||||||
|
[34mid[39m: [35m13[39m,
|
||||||
|
[34mgroup[39m: "[32mwoltguard[39m",
|
||||||
|
[34mkey[39m: "[32mservices[39m",
|
||||||
|
[34mvalue[39m: "[32m{"ts":1761504019,"rows":[{"name":"postfix","ok":true},{"name":"dovecot","ok":true},{"name":"rspamd","ok":true},{"name":"clamav","ok":true},{"name":"db","ok":true},{"name":"redis","ok":true},{"name":"php-fpm","ok":true},{"name":"nginx","ok":true},{"name":"mw-queue","ok":true},{"name":"mw-schedule","ok":true},{"name":"mw-ws","ok":true},{"name":"fail2ban","ok":true},{"name":"journal","ok":true}]}[39m",
|
||||||
|
[34mcreated_at[39m: "[32m2025-10-26 19:40:19[39m",
|
||||||
|
[34mupdated_at[39m: "[32m2025-10-26 19:40:19[39m",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -33,13 +33,11 @@ class RunHealthChecks implements ShouldQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache::put(CacheVer::k('health:services'), $svcRows, 60);
|
// Cache::put(CacheVer::k('health:services'), $svcRows, 60);
|
||||||
Cache::put(CacheVer::k('health:services'), [
|
|
||||||
'ts' => time(),
|
$payload = ['ts' => time(), 'rows' => $svcRows];
|
||||||
'rows' => $svcRows,
|
Cache::put(CacheVer::k('health:services'), $payload, 300);
|
||||||
], 300);
|
Setting::set('woltguard.services', $payload);
|
||||||
Setting::set('woltguard.services', ['ts' => time(), 'rows' => $svcRows]);
|
Cache::forget('health:services'); }
|
||||||
Cache::forget('health:services');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Wraps a probe; logs and returns fallback on error */
|
/** Wraps a probe; logs and returns fallback on error */
|
||||||
protected function safe(callable $fn, $fallback = null)
|
protected function safe(callable $fn, $fallback = null)
|
||||||
|
|
|
||||||
|
|
@ -48,57 +48,110 @@ class WoltguardCard extends Component
|
||||||
|
|
||||||
protected function load(): void
|
protected function load(): void
|
||||||
{
|
{
|
||||||
// 1) Primär: Redis
|
// 1) Primär: versionierter Cache-Key (mit ts/rows)
|
||||||
$data = Cache::get(CacheVer::k('health:services'));
|
$data = Cache::get(CacheVer::k('health:services'));
|
||||||
|
|
||||||
// 2) Fallback: Settings (DB)
|
// 2) Fallback: Settings (DB) wenn Cache leer/fehlend
|
||||||
if (!is_array($data) || empty($data['rows'])) {
|
if (!is_array($data) || empty($data['rows'])) {
|
||||||
$data = Setting::get('woltguard.services', []);
|
$data = \App\Models\Setting::get('woltguard.services', []);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) Falls beides leer → letzter bekannter Zustand beibehalten
|
// 3) Letzter bekannter Zustand als Notanker (kein Flackern)
|
||||||
$rows = $data['rows'] ?? [];
|
$rows = $data['rows'] ?? [];
|
||||||
if (empty($rows) && !empty($this->services)) {
|
if (empty($rows) && !empty($this->services)) {
|
||||||
$rows = $this->services;
|
$rows = $this->services;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mapping
|
// ---- Mapping in UI-Props ----
|
||||||
$this->services = $rows;
|
$this->services = $rows;
|
||||||
$this->totalCount = count($rows);
|
$this->totalCount = count($rows);
|
||||||
$this->okCount = collect($rows)->where('ok', true)->count();
|
$this->okCount = collect($rows)->where('ok', true)->count();
|
||||||
$this->downCount = max(0, $this->totalCount - $this->okCount);
|
$this->downCount = max(0, $this->totalCount - $this->okCount);
|
||||||
$this->guardOk = ($this->totalCount > 0) && ($this->downCount === 0);
|
$this->guardOk = ($this->totalCount > 0) && ($this->downCount === 0);
|
||||||
|
|
||||||
$this->downServices = collect($rows)
|
$this->downServices = collect($rows)
|
||||||
->filter(fn($s) => !($s['ok'] ?? false))
|
->filter(fn ($s) => !($s['ok'] ?? false))
|
||||||
->map(fn($s) => (string)($s['name'] ?? 'unbekannt'))
|
->map(fn ($s) => (string)($s['name'] ?? 'unbekannt'))
|
||||||
->values()
|
->values()
|
||||||
->all();
|
->all();
|
||||||
|
|
||||||
// Badges
|
// Badge
|
||||||
if ($this->totalCount === 0) {
|
if ($this->totalCount === 0) {
|
||||||
$this->badgeText = 'keine Daten';
|
$this->badgeText = 'keine Daten';
|
||||||
$this->badgeIcon = 'ph ph-warning-circle';
|
$this->badgeIcon = 'ph ph-warning-circle';
|
||||||
$this->badgeClass = 'text-amber-300 border-amber-400/30 bg-amber-500/10';
|
$this->badgeClass = 'text-amber-300 border-amber-400/30 bg-amber-500/10';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->guardOk) {
|
if ($this->guardOk) {
|
||||||
$this->badgeText = 'alle Dienste OK';
|
$this->badgeText = 'alle Dienste OK';
|
||||||
$this->badgeIcon = 'ph ph-check-circle';
|
$this->badgeIcon = 'ph ph-check-circle';
|
||||||
$this->badgeClass = 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10';
|
$this->badgeClass = 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10';
|
||||||
} else {
|
} else {
|
||||||
if ($this->downCount >= 3) {
|
if ($this->downCount >= 3) {
|
||||||
$this->badgeText = "{$this->downCount} Dienste down";
|
$this->badgeText = "{$this->downCount} Dienste down";
|
||||||
$this->badgeIcon = 'ph ph-x-circle';
|
$this->badgeIcon = 'ph ph-x-circle';
|
||||||
$this->badgeClass = 'text-rose-300 border-rose-400/30 bg-rose-500/10';
|
$this->badgeClass = 'text-rose-300 border-rose-400/30 bg-rose-500/10';
|
||||||
} else {
|
} else {
|
||||||
$this->badgeText = 'Störung erkannt';
|
$this->badgeText = 'Störung erkannt';
|
||||||
$this->badgeIcon = 'ph ph-warning-circle';
|
$this->badgeIcon = 'ph ph-warning-circle';
|
||||||
$this->badgeClass = 'text-amber-300 border-amber-400/30 bg-amber-500/10';
|
$this->badgeClass = 'text-amber-300 border-amber-400/30 bg-amber-500/10';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// protected function load(): void
|
||||||
|
// {
|
||||||
|
// // 1) Primär: Redis
|
||||||
|
// $data = Cache::get(CacheVer::k('health:services'));
|
||||||
|
//
|
||||||
|
// // 2) Fallback: Settings (DB)
|
||||||
|
// if (!is_array($data) || empty($data['rows'])) {
|
||||||
|
// $data = Setting::get('woltguard.services', []);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 3) Falls beides leer → letzter bekannter Zustand beibehalten
|
||||||
|
// $rows = $data['rows'] ?? [];
|
||||||
|
// if (empty($rows) && !empty($this->services)) {
|
||||||
|
// $rows = $this->services;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Mapping
|
||||||
|
// $this->services = $rows;
|
||||||
|
// $this->totalCount = count($rows);
|
||||||
|
// $this->okCount = collect($rows)->where('ok', true)->count();
|
||||||
|
// $this->downCount = max(0, $this->totalCount - $this->okCount);
|
||||||
|
// $this->guardOk = ($this->totalCount > 0) && ($this->downCount === 0);
|
||||||
|
//
|
||||||
|
// $this->downServices = collect($rows)
|
||||||
|
// ->filter(fn($s) => !($s['ok'] ?? false))
|
||||||
|
// ->map(fn($s) => (string)($s['name'] ?? 'unbekannt'))
|
||||||
|
// ->values()
|
||||||
|
// ->all();
|
||||||
|
//
|
||||||
|
// // Badges
|
||||||
|
// if ($this->totalCount === 0) {
|
||||||
|
// $this->badgeText = 'keine Daten';
|
||||||
|
// $this->badgeIcon = 'ph ph-warning-circle';
|
||||||
|
// $this->badgeClass = 'text-amber-300 border-amber-400/30 bg-amber-500/10';
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if ($this->guardOk) {
|
||||||
|
// $this->badgeText = 'alle Dienste OK';
|
||||||
|
// $this->badgeIcon = 'ph ph-check-circle';
|
||||||
|
// $this->badgeClass = 'text-emerald-300 border-emerald-400/30 bg-emerald-500/10';
|
||||||
|
// } else {
|
||||||
|
// if ($this->downCount >= 3) {
|
||||||
|
// $this->badgeText = "{$this->downCount} Dienste down";
|
||||||
|
// $this->badgeIcon = 'ph ph-x-circle';
|
||||||
|
// $this->badgeClass = 'text-rose-300 border-rose-400/30 bg-rose-500/10';
|
||||||
|
// } else {
|
||||||
|
// $this->badgeText = 'Störung erkannt';
|
||||||
|
// $this->badgeIcon = 'ph ph-warning-circle';
|
||||||
|
// $this->badgeClass = 'text-amber-300 border-amber-400/30 bg-amber-500/10';
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
// protected function load(): void
|
// protected function load(): void
|
||||||
// {
|
// {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue