/* * Protokollseite: die Logdateien der Hintergrundprozesse ansehen. * * Die Seite haelt nichts vor - jede Anfrage holt frisch die letzten N Zeilen * vom Server. Das ist Absicht: ein Log wird von hinten gelesen, und wer * blaettert, will ohnehin filtern statt scrollen. Der Server liest die Datei * dafuer rueckwaerts, ein Blick in die 300-MB-Datei der Wallbox kostet * deshalb so viel wie einer in die kleine des Weckers. * * Gezeichnet wird aus der Antwort, nicht aus dem DOM. Die einzige Sache, die * ueber einen Aufruf hinaus bestehen bleibt, ist die zuletzt gewaehlte Datei * im localStorage - damit man nach dem Neuladen dort weitermacht, wo man war. */ (function () { "use strict"; const liste = document.querySelector(".log-liste"); if (!liste) return; // andere Seite const ausgabe = document.querySelector(".log-ausgabe"); const hinweis = document.querySelector(".log-hinweis"); const titel = document.querySelector(".log-titel"); const standTxt = document.querySelector(".log-stand"); const suche = document.querySelector(".log-suche"); const level = document.querySelector(".log-level"); const anzahl = document.querySelector(".log-anzahl"); const folgen = document.querySelector(".log-folgen"); const SPEICHER = "logDateiWahl"; // Direkt und nicht ueber window: die Seite deklariert den Ausgangsstand mit // const, und das legt nichts auf window ab. let dateien = (typeof logDateienStand !== "undefined" && Array.isArray(logDateienStand)) ? logDateienStand : []; let gewaehlt = localStorage.getItem(SPEICHER) || (dateien[0] && dateien[0].key) || "runner"; let uhr = null; let abbruch = null; // laufende Anfrage, siehe laden() // --- Kleinkram ---------------------------------------------------------- function escape(s) { return String(s === null || s === undefined ? "" : s) .replace(/&/g, "&").replace(//g, ">"); } /** 345351905 -> "329,4 MB" */ function groesse(bytes) { if (!bytes) return "leer"; const einheiten = ["B", "kB", "MB", "GB"]; let i = 0, z = bytes; while (z >= 1024 && i < einheiten.length - 1) { z /= 1024; i++; } return (i === 0 ? z : z.toFixed(1).replace(".", ",")) + " " + einheiten[i]; } /** * "vor 3 Minuten". Wichtiger als der Zeitstempel selbst: eine Datei, die * seit Tagen nicht gewachsen ist, gehoert angesehen. */ function alter(stand) { if (!stand) return ""; const sek = (Date.now() - new Date(stand.replace(" ", "T")).getTime()) / 1000; if (sek < 90) return "gerade eben"; if (sek < 5400) return "vor " + Math.round(sek / 60) + " min"; if (sek < 172800) return "vor " + Math.round(sek / 3600) + " h"; return "vor " + Math.round(sek / 86400) + " Tagen"; } /** Ab wann eine Datei als eingeschlafen gilt - grob, nur zum Einfaerben. */ function eingeschlafen(stand) { if (!stand) return true; return (Date.now() - new Date(stand.replace(" ", "T")).getTime()) > 24 * 3600 * 1000; } // --- Dateiliste --------------------------------------------------------- function listeZeichnen() { liste.innerHTML = dateien.map(function (d) { const aktiv = d.key === gewaehlt ? " active" : ""; let zustand; if (!d.da) { zustand = 'gibt es nicht'; } else if (!d.lesbar) { zustand = 'nicht lesbar'; } else { const farbe = eingeschlafen(d.stand) ? "text-warning" : "text-secondary"; zustand = '' + escape(alter(d.stand)) + "" + ' · ' + escape(groesse(d.groesse)) + ""; } return '"; }).join(""); } function zustandLaden() { return fetch("ajax/logs.php?action=list", { cache: "no-store" }) .then(function (r) { return r.json(); }) .then(function (a) { if (a.dateien) { dateien = a.dateien; listeZeichnen(); } }) .catch(function () { /* der naechste Versuch kommt bestimmt */ }); } // --- Zeilen ------------------------------------------------------------- const KLASSE = { DEBUG: "log-debug", INFO: "log-info", WARNING: "log-warning", ERROR: "log-error", CRITICAL: "log-error" }; function zeilenZeichnen(antwort) { const zeilen = antwort.zeilen || []; if (!zeilen.length) { // Eine leere Datei und ein Filter ohne Treffer sehen gleich aus, sind // aber zwei verschiedene Befunde: das eine heisst "der Prozess hat noch // nichts gesagt", das andere "such woanders". const leer = (antwort.zustand || {}).groesse === 0; ausgabe.innerHTML = '