Replace stale Grafana hero with live operations panel

This commit is contained in:
Keith Casko
2026-10-02 10:53:43 -04:00
parent 9e62baced4
commit 62fc9fe0f4
3 changed files with 180 additions and 9 deletions
+54 -5
View File
@@ -8,6 +8,16 @@ const fields = {
containers: document.querySelector("#containers-value"),
targets: document.querySelector("#targets-value"),
telemetry: document.querySelector("#telemetry-value"),
opsCpu: document.querySelector("#ops-cpu-value"),
opsMemory: document.querySelector("#ops-memory-value"),
opsUptime: document.querySelector("#ops-uptime-value"),
opsContainers: document.querySelector("#ops-containers-value"),
opsTargets: document.querySelector("#ops-targets-value"),
};
const telemetryHistory = {
cpu: [],
memory: [],
};
let lastSuccessfulUpdate = null;
@@ -41,17 +51,56 @@ function setUnavailable() {
}
fields.telemetry.textContent = "UNAVAILABLE";
fields.telemetry.classList.add("metric-error");
fields.opsCpu.textContent = "--%";
fields.opsMemory.textContent = "--%";
fields.opsUptime.textContent = "--";
fields.opsContainers.textContent = "--";
fields.opsTargets.textContent = "--";
refreshElement.textContent = "TELEMETRY UNAVAILABLE";
refreshElement.classList.add("telemetry-error");
}
function renderOpsBars(elementId, values) {
const container = document.querySelector(elementId);
if (!container) return;
container.replaceChildren();
values.forEach((value) => {
const bar = document.createElement("i");
bar.style.setProperty("--bar-height", Math.max(4, Math.min(100, value)) + "%");
container.appendChild(bar);
});
}
function pushHistory(series, value) {
series.push(value);
if (series.length > 24) series.shift();
}
function renderStatus(data) {
fields.cpu.textContent = Number(data.host.cpu_percent).toFixed(1);
fields.memory.textContent = Number(data.host.memory_percent).toFixed(1);
fields.uptime.textContent = formatUptime(data.host.uptime_seconds);
fields.containers.textContent = String(data.containers.running);
fields.targets.textContent = data.prometheus.up + "/" + data.prometheus.total;
const cpu = Number(data.host.cpu_percent);
const memory = Number(data.host.memory_percent);
const uptime = formatUptime(data.host.uptime_seconds);
const containers = String(data.containers.running);
const targets = data.prometheus.up + "/" + data.prometheus.total;
fields.cpu.textContent = cpu.toFixed(1);
fields.memory.textContent = memory.toFixed(1);
fields.uptime.textContent = uptime;
fields.containers.textContent = containers;
fields.targets.textContent = targets;
fields.telemetry.textContent = "LIVE";
fields.opsCpu.textContent = cpu.toFixed(1) + "%";
fields.opsMemory.textContent = memory.toFixed(1) + "%";
fields.opsUptime.textContent = uptime;
fields.opsContainers.textContent = containers;
fields.opsTargets.textContent = targets;
pushHistory(telemetryHistory.cpu, cpu);
pushHistory(telemetryHistory.memory, memory);
renderOpsBars("#ops-cpu-bars", telemetryHistory.cpu);
renderOpsBars("#ops-memory-bars", telemetryHistory.memory);
fields.telemetry.classList.remove("metric-error");
refreshElement.classList.remove("telemetry-error");