diff --git a/index.html b/index.html
index 5a428c7..5389379 100644
--- a/index.html
+++ b/index.html
@@ -119,11 +119,32 @@
-
GRAFANA / BYTEGEIST OPERATIONS
-
FULL RES ↗
+
BYTEGEIST / LIVE OPERATIONS
+
PROMETHEUS / NODE EXPORTER / CADVISOR
-

-
CAPTURED OCT 2026 · GRAFANA OPERATIONS SNAPSHOT · LIVE VALUES ABOVE REFRESH EVERY 15s
+
+
+
+
+
HOST UPTIME--
+
CONTAINERS--
+
SCRAPE TARGETS--
+
REFRESH15s
+
+
+
LIVE OPERATIONS VIEW · VALUES COME FROM THE SAME SANITIZED /API/STATUS TELEMETRY FEED
diff --git a/script.js b/script.js
index a7a49b8..46c8caa 100644
--- a/script.js
+++ b/script.js
@@ -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");
diff --git a/style.css b/style.css
index bc01dda..3da7a9e 100644
--- a/style.css
+++ b/style.css
@@ -460,6 +460,94 @@ h1 {
border: 1px solid #20232a;
}
+.live-ops-panel {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 1px;
+ border: 1px solid #20232a;
+ background: var(--line);
+}
+
+.ops-chart,
+.ops-status-grid {
+ background: #070a0f;
+}
+
+.ops-chart {
+ min-height: 150px;
+ padding: 16px;
+}
+
+.ops-chart-head {
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
+ gap: 12px;
+}
+
+.ops-chart-head span,
+.ops-status-grid span {
+ color: var(--dim);
+ font: .56rem var(--mono);
+ letter-spacing: .08em;
+}
+
+.ops-chart-head strong {
+ color: var(--green);
+ font: 500 1.1rem var(--mono);
+}
+
+.ops-bars {
+ height: 86px;
+ margin-top: 18px;
+ display: flex;
+ align-items: flex-end;
+ gap: 4px;
+ border-bottom: 1px solid #26313c;
+ background:
+ linear-gradient(to top, transparent 24%, #121820 25%, transparent 26%, transparent 49%, #121820 50%, transparent 51%, transparent 74%, #121820 75%, transparent 76%);
+}
+
+.ops-bars i {
+ flex: 1 1 0;
+ min-width: 3px;
+ height: var(--bar-height, 4%);
+ background: var(--green);
+ opacity: .72;
+ transition: height .25s ease;
+}
+
+.ops-chart:nth-child(2) .ops-bars i {
+ background: var(--cyan);
+}
+
+.ops-status-grid {
+ grid-column: 1 / -1;
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 1px;
+ background: var(--line);
+}
+
+.ops-status-grid div {
+ min-height: 70px;
+ padding: 13px 16px;
+ background: #080c12;
+}
+
+.ops-status-grid strong {
+ display: block;
+ margin-top: 9px;
+ color: var(--muted);
+ font: 500 .82rem var(--mono);
+}
+
+.window-bar small {
+ color: var(--dim);
+ font: .52rem var(--mono);
+ letter-spacing: .05em;
+}
+
.activity-panel {
padding: 24px 18px;
border-left: 1px solid var(--line);
@@ -1191,6 +1279,19 @@ footer {
grid-template-columns: 1fr 1fr;
}
+ .live-ops-panel {
+ grid-template-columns: 1fr;
+ }
+
+ .ops-status-grid {
+ grid-column: 1;
+ grid-template-columns: 1fr 1fr;
+ }
+
+ .window-bar small {
+ display: none;
+ }
+
.metric {
min-height: 112px;
}