Watchdog: Embeds statt Textzeilen, dazu eine Uebersicht im Panel
Deploy / check (push) Has been cancelled
Deploy / deploy (push) Has been cancelled

Die DM-Alarme waren als einzige Meldung noch reiner Text — direkt neben dem
Raid-Alarm, der ein Embed ist. Jetzt beide im selben Look, mit Ausfalldauer
bzw. Fehlergrund und Antwortzeit als Felder.

Uebersicht im Panel (System, unter den Watchdog-URLs): je Adresse ein
Erreichbarkeits-Balken ueber 7 Tage, gruen/rot/grau wie bei den Game-Servern,
dazu Status, Antwortzeit und seit wann etwas weg ist.

Dafuer schreibt der Waechter jetzt mit — vorher lebte sein Zustand nur im
Speicher und war nach jedem Neustart weg. Neue Tabelle watchdog_history,
gleiche Bauart und gleiche 7-Tage-Aufbewahrung wie player_history, stundenweise
zusammengefasst statt roh ausgeliefert.

Wichtig dabei: aufgezeichnet wird jeder Check, nicht nur die Wechsel. Sonst
saehen ruhige Stunden im Balken aus wie Messluecken.

Der Balken ist aus Server.jsx in components/UptimeTrack.jsx gewandert, damit
oeffentliche Seite und Panel denselben benutzen. Er zeigt die Antwortzeit im
Tooltip nur, wo sie erhoben wird — bei Game-Servern gibt es keine.

Der Endpunkt /api/watchdog liegt hinter der Rechtepruefung, nicht oeffentlich:
in der Adressliste koennen interne Dienste stehen.

Zwei fehlende Importe in api.js gefunden und ergaenzt (moduleEnabled, tuning) —
der erste Aufruf der Route waere sonst mit ReferenceError gestorben.

Geprueft: alle 171 SQL-Abfragen gegen das Schema, die drei neuen inklusive.
Im Browser mit drei Faellen — laeuft, ist weg, noch nie geprueft: Punktfarbe,
Quote, Ausfallstunden und Messluecken stimmen, die ungepruefte Adresse zeigt
korrekt gar keinen Balken. Oeffentliche Server-Seite nach dem Umbau
gegengeprueft.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-01 05:28:22 +02:00
co-authored by Claude Fable 5
parent 2d4afad3cb
commit fd2d31f07f
7 changed files with 222 additions and 78 deletions
+28
View File
@@ -10,6 +10,7 @@ import {
} from '../icons.jsx';
import { moduleIcon } from '../module-icons.jsx';
import ModulePage from '../components/ModulePage.jsx';
import UptimeTrack from '../components/UptimeTrack.jsx';
import { findSettings, SETTING_INDEX } from '../setting-index.js';
import { Markdown } from '../markdown.jsx';
@@ -341,6 +342,7 @@ export default function Settings({ me }) {
const [team, setTeam] = useState([]);
const [audit, setAudit] = useState([]);
const [serverStats, setServerStats] = useState(null);
const [watchdog, setWatchdog] = useState(null);
const [owner, setOwner] = useState(null);
const [auditAlle, setAuditAlle] = useState(false);
// Module (An/Aus für alle Funktionen)
@@ -467,6 +469,7 @@ export default function Settings({ me }) {
apiGet('/api/auditlog').then((d) => setAudit(d.entries)).catch(() => {});
// Fuers Dashboard: Mitgliederzahl und Nachrichten pro Tag
apiGet('/api/serverstats').then(setServerStats).catch(() => {});
apiGet('/api/watchdog').then(setWatchdog).catch(() => {});
apiGet('/api/ssoapps').then((d) => setSsoApps(d.apps)).catch(() => {});
apiGet('/api/services').then((d) => setServices(d.services)).catch(() => {});
apiGet('/api/pages/all/list').then((d) => setPages(d.pages)).catch(() => {});
@@ -2337,6 +2340,31 @@ export default function Settings({ me }) {
<input type="text" placeholder="https://git.d4rkst3r.de, https://bot.d4rkst3r.de/health" value={form.watchdog_urls} onChange={(e) => setForm({ ...form, watchdog_urls: e.target.value })} />
</div>
</div>
{watchdog?.adressen?.length > 0 && (
<div className="settings-section">
<h2 className="settings-title">// Erreichbarkeit</h2>
<p className="section-intro">
Ein Strich je Stunde über die letzten 7 Tage grün erreichbar, rot
Ausfall, grau keine Messung. Geprüft wird alle {watchdog.intervall} Minuten.
{!watchdog.aktiv && ' Der Wächter ist gerade ausgeschaltet, es kommen keine neuen Messpunkte dazu.'}
</p>
{watchdog.adressen.map((a) => (
<div className="wd-card card" key={a.url}>
<div className="wd-head">
<span className={`wd-dot ${a.online === null ? 'wartet' : a.online ? 'an' : 'aus'}`} />
<a className="wd-url" href={a.url} target="_blank" rel="noreferrer">{a.url}</a>
<span className="wd-meta">
{a.online === null && 'noch nicht geprüft'}
{a.online === true && `${a.status ?? 'OK'}${a.ms != null ? ` · ${a.ms} ms` : ''}`}
{a.online === false && `seit ${vorWieLange(new Date(a.seit).toISOString())} weg`}
</span>
</div>
<UptimeTrack buckets={a.uptime} />
</div>
))}
</div>
)}
</>
);