121 lines
4.2 KiB
JavaScript
Executable File
121 lines
4.2 KiB
JavaScript
Executable File
/* AES-Suite Live-Monitoring — pollt monitor.json und rendert Dienste +
|
|
Backends grafisch. Von /static ausgeliefert (CSP script-src 'self'). */
|
|
(function () {
|
|
"use strict";
|
|
var root = document.getElementById("aes-monitor");
|
|
if (!root) return;
|
|
var src = root.getAttribute("data-src") || "/erweiterungen/aes/monitor.json";
|
|
var INTERVAL = 5000;
|
|
|
|
function el(tag, cls, text) {
|
|
var e = document.createElement(tag);
|
|
if (cls) e.className = cls;
|
|
if (text != null) e.textContent = text;
|
|
return e;
|
|
}
|
|
|
|
function bar(label, pct) {
|
|
var wrap = el("div", "sz");
|
|
wrap.style.margin = "2px 0";
|
|
var v = Math.max(0, Math.min(100, Math.round(pct || 0)));
|
|
wrap.appendChild(document.createTextNode(label + " "));
|
|
var track = el("span");
|
|
track.style.display = "inline-block";
|
|
track.style.width = "120px";
|
|
track.style.height = "8px";
|
|
track.style.borderRadius = "4px";
|
|
track.style.background = "var(--border, #333)";
|
|
track.style.verticalAlign = "middle";
|
|
track.style.margin = "0 6px";
|
|
var fill = el("span");
|
|
fill.style.display = "block";
|
|
fill.style.height = "8px";
|
|
fill.style.borderRadius = "4px";
|
|
fill.style.width = v + "%";
|
|
fill.style.background = v > 85 ? "#d9534f" : (v > 60 ? "#e0a800" : "#3fb950");
|
|
track.appendChild(fill);
|
|
wrap.appendChild(track);
|
|
wrap.appendChild(document.createTextNode(v + "%"));
|
|
return wrap;
|
|
}
|
|
|
|
function render(data) {
|
|
root.textContent = "";
|
|
|
|
// Dienst-Ampeln
|
|
var svcRow = el("div");
|
|
svcRow.style.display = "flex";
|
|
svcRow.style.flexWrap = "wrap";
|
|
svcRow.style.gap = "10px";
|
|
(data.services || []).forEach(function (s) {
|
|
var card = el("div", "card");
|
|
card.style.flex = "1";
|
|
card.style.minWidth = "180px";
|
|
var head = el("div");
|
|
head.style.display = "flex";
|
|
head.style.justifyContent = "space-between";
|
|
head.style.alignItems = "center";
|
|
head.appendChild(el("b", null, s.name));
|
|
head.appendChild(el("span", "badge " + (s.ok ? "ok" : "err"), s.ok ? "up" : "down"));
|
|
card.appendChild(head);
|
|
card.appendChild(el("div", "sz", s.detail || ""));
|
|
svcRow.appendChild(card);
|
|
});
|
|
root.appendChild(svcRow);
|
|
|
|
// Backends
|
|
var h = el("h3", null, "Backends / Agenten");
|
|
h.style.margin = "16px 0 6px";
|
|
root.appendChild(h);
|
|
var bes = data.backends || [];
|
|
if (!bes.length) {
|
|
root.appendChild(el("p", "sz", "Keine Backends online."));
|
|
} else {
|
|
bes.forEach(function (b) {
|
|
var card = el("div", "card");
|
|
var head = el("div");
|
|
head.style.display = "flex";
|
|
head.style.justifyContent = "space-between";
|
|
head.appendChild(el("b", null, b.url));
|
|
head.appendChild(el("span", "badge " + (b.healthy ? "ok" : "err"), b.healthy ? "healthy" : "offline"));
|
|
card.appendChild(head);
|
|
card.appendChild(bar("CPU", b.cpu));
|
|
card.appendChild(bar("RAM", b.ram));
|
|
card.appendChild(bar("VRAM", b.vram));
|
|
var meta = el("div", "sz");
|
|
meta.textContent = "Latenz " + (b.latency || 0) + "ms · Agent " + (b.agent_online ? "online" : "offline") +
|
|
" · Modelle: " + ((b.models && b.models.length) ? b.models.join(", ") : "-");
|
|
card.appendChild(meta);
|
|
root.appendChild(card);
|
|
});
|
|
}
|
|
|
|
// Runner + Projekte + Zeitstempel
|
|
var foot = el("p", "sz");
|
|
foot.style.marginTop = "10px";
|
|
var r = data.runner || {};
|
|
foot.textContent = "Runner: " + (r.available ? "aktiv" : "offline") +
|
|
" · beobachtete Repos: " + ((r.watched && r.watched.length) || 0) +
|
|
" · Projekte: " + (data.projects_total || 0) +
|
|
" · Stand: " + new Date().toLocaleTimeString();
|
|
root.appendChild(foot);
|
|
}
|
|
|
|
function tick() {
|
|
fetch(src, { headers: { "Accept": "application/json" }, credentials: "same-origin" })
|
|
.then(function (r) { return r.json(); })
|
|
.then(render)
|
|
.catch(function () {
|
|
var p = document.getElementById("aes-monitor-err");
|
|
if (!p) {
|
|
p = el("p", "err", "Live-Daten momentan nicht abrufbar — naechster Versuch laeuft.");
|
|
p.id = "aes-monitor-err";
|
|
root.appendChild(p);
|
|
}
|
|
});
|
|
}
|
|
|
|
tick();
|
|
setInterval(tick, INTERVAL);
|
|
})();
|