feat: der Monitor fragt das Panel, wenn eine Abfrage nicht ausreicht
gamedig FRAGT einen Server. Ein startendes Modpack antwortet nicht, und
nach zwei Fehlversuchen stand im Alarm-Kanal eine Ausfallmeldung, obwohl
niemand etwas kaputtgemacht hat -- am ATM10 des Betreibers gemessen jedes
Mal 306 Sekunden Fehlalarm.
Das d4rk_gameserver-Panel SIEHT den Container, statt ihn zu fragen. Neu
ist deshalb `src/panel.js`: Zustand, Fertig-Merkmal, RAM und CPU kommen
als Zusatzauskunft dazu, einmal je Durchlauf abgerufen und 20 Sekunden
zwischengespeichert.
Was das im Alarm-Kanal aendert:
startet gerade kein Alarm, aber nur innerhalb einer Gnadenfrist von
15 Minuten. Ohne diese Grenze fraesse die Anbindung
genau den Alarm, fuer den es sie gibt -- `bereit`
wird nie von allein wahr, ein haengender Start bliebe
sonst fuer immer stumm.
im Panel gestoppt kein Alarm (Code 0/143/137)
abgestuerzt ALARM, mit Code im Embed
OOM-Kill ALARM, und beim Namen genannt statt als Absturz
getarnt -- bei Modpacks die haeufigste Ursache
Container weg ALARM
Der Zaehler wird beim Unterdruecken NICHT zurueckgesetzt: ein bereits
gemeldeter Ausfall bleibt gemeldet, sonst verschluckt ein Stopp im Panel
die spaetere "wieder online"-Entwarnung und im Kanal bliebe ein Alarm
ohne Aufloesung stehen.
ES IST DURCHGEHEND OPTIONAL. Adresse und Zeichen stehen im Webinterface
unter "Server" und NICHT in der .env; ohne Eintrag -- und ebenso, wenn
das Panel nicht antwortet -- verhaelt sich der Monitor exakt wie vorher.
Das Zeichen darf nur lesen, damit auch ein verlorenes niemandem einen
Server stoppen kann.
`tools/panel-pruefen.mjs` prueft die Logik ohne Discord und ohne
Datenbank; deshalb laedt panel.js die Einstellungen erst beim Aufruf.
This commit is contained in:
@@ -8,6 +8,7 @@ import { brandFooter, botStatusText } from '../runtime-settings.js';
|
||||
import { brandEmbed } from '../embeds.js';
|
||||
import { moduleEnabled } from '../modules.js';
|
||||
import { tuning, tuningMs, everyTuned } from '../tuning.js';
|
||||
import { panelStatus, panelEintrag, zustandText, lastText, startetNoch, gewolltAus } from '../panel.js';
|
||||
|
||||
const GREEN = 0x23a55a;
|
||||
const RED = 0xf23f43;
|
||||
@@ -257,8 +258,14 @@ export function buildServerEmbed(r) {
|
||||
// nicht verlässlich, und dann stünde das Steuerzeichen wörtlich da.
|
||||
kopf.push(`*${r.spielname.trim().slice(0, 200)}*`);
|
||||
}
|
||||
// Wenn GameDig nichts erreicht hat, das Panel aber sagt, dass der
|
||||
// Container laeuft und noch startet: DAS ist die richtige Auskunft. Ein
|
||||
// Modpack braucht Minuten bis zum ersten Spieler -- am ATM10 des
|
||||
// Betreibers 306 Sekunden -- und ein rotes "Offline" waere in dieser Zeit
|
||||
// schlicht falsch.
|
||||
const ausPanel = r.online ? null : zustandText(r.panel);
|
||||
kopf.push([
|
||||
r.online ? '🟢 **Online**' : '🔴 **Offline**',
|
||||
r.online ? '🟢 **Online**' : (ausPanel ?? '🔴 **Offline**'),
|
||||
zugang.grund ? `🔒 ${zugang.grund}` : null,
|
||||
r.online && r.ping != null ? `${r.ping} ms` : null,
|
||||
].filter(Boolean).join(' · '));
|
||||
@@ -276,6 +283,12 @@ export function buildServerEmbed(r) {
|
||||
r.mods != null ? { name: 'Mods', value: String(r.mods), inline: true } : null,
|
||||
]));
|
||||
|
||||
// Was nur das Panel weiss: was der Server gerade verbraucht.
|
||||
{
|
||||
const last = lastText(r.panel);
|
||||
if (last) embed.addFields({ name: 'Auf dem Wirt', value: last });
|
||||
}
|
||||
|
||||
if (r.online && r.playerNames.length > 0) {
|
||||
embed.addFields({
|
||||
name: `Wer drauf ist (${r.playerNames.length})`,
|
||||
@@ -318,6 +331,31 @@ async function handleAlerts(client, r) {
|
||||
alertState.set(r.id, { fails: 0, down: false, since: null });
|
||||
return;
|
||||
}
|
||||
|
||||
// KEIN ALARM, WENN DAS PANEL DEN ZUSTAND ERKLÄREN KANN.
|
||||
//
|
||||
// Das ist der eigentliche Gewinn der Anbindung. GameDig *fragt* einen
|
||||
// Server; ein startender antwortet nicht, und nach zwei Fehlversuchen
|
||||
// stünde hier eine Ausfallmeldung. Bei einem Modpack sind das jedes Mal
|
||||
// Minuten Fehlalarm — am ATM10 des Betreibers 306 Sekunden bis zum ersten
|
||||
// Spieler. Das Panel *sieht* den Container und weiß, dass er läuft und
|
||||
// nur das Fertig-Merkmal noch nicht durch ist.
|
||||
//
|
||||
// Zwei Fälle, eine Behandlung: nichts tun. Der Zähler bleibt dabei
|
||||
// ausdrücklich STEHEN statt zurückgesetzt zu werden, aus zwei Gründen:
|
||||
//
|
||||
// - Läuft die Gnadenfrist ab, ohne dass der Server fertig wird, greift
|
||||
// `startetNoch` nicht mehr und der Alarm kommt sofort statt erst nach
|
||||
// zwei weiteren Durchläufen.
|
||||
// - Ein bereits gemeldeter Ausfall bleibt gemeldet. Sonst verschluckt
|
||||
// ein Stopp im Panel die spätere „✅ wieder online"-Entwarnung, und im
|
||||
// Alarm-Kanal bliebe ein 🚨 ohne Auflösung stehen.
|
||||
//
|
||||
// Und was NICHT unterdrückt wird: ein Absturz, ein OOM-Kill und ein
|
||||
// fehlender Container. Das sind die Fälle, für die es den Kanal gibt —
|
||||
// hier hilft das Panel dem Alarm, statt ihn zu ersetzen.
|
||||
if (startetNoch(r.panel) || gewolltAus(r.panel)) return;
|
||||
|
||||
const fails = s.fails + 1;
|
||||
if (!s.down && fails >= tuning('monitor_fails')) {
|
||||
const channel = await client.channels.fetch(channelId).catch(() => null);
|
||||
@@ -343,6 +381,12 @@ export async function monitorTick(client) {
|
||||
|
||||
const results = await Promise.all(servers.map(queryServer));
|
||||
|
||||
// Die Zusatzauskunft vom Panel: EINMAL je Durchlauf, nicht je Server.
|
||||
// Sie ist optional -- ist nichts eingetragen oder antwortet das Panel
|
||||
// nicht, bleibt `panel` schlicht null und alles läuft wie vorher.
|
||||
const panelItems = await panelStatus();
|
||||
for (const r of results) r.panel = panelEintrag(panelItems, r);
|
||||
|
||||
// Verlauf für die Web-Seite festhalten + Cache fürs API
|
||||
for (const r of results) {
|
||||
lastResults.set(r.id, { ...r, checkedAt: Date.now() });
|
||||
|
||||
Reference in New Issue
Block a user