v0.33.0
This commit is contained in:
1 parent
bbfa8cbc3f
commit
2ccc598b12
49 files changed
+4771
-639
No files matched your search
@@ -392,11 +392,70 @@
|
||||
item.append(el("span", t(key), "small-label"), el("b", value));
|
||||
details.append(item);
|
||||
}
|
||||
box.append(details); return box;
|
||||
const live = el("details", undefined, "www-service-panel");
|
||||
const summary = el("summary", t("webLiveMetrics")); live.append(summary);
|
||||
const panel = el("div", undefined, "www-service-live"); panel.dataset.webLiveId = service.id;
|
||||
const figures = el("div", undefined, "www-service-values");
|
||||
for (const [field, key] of [
|
||||
["requests", "webLiveRequests"], ["rate", "webLiveRate"],
|
||||
["errors", "webLiveErrors"], ["latency", "webLiveLatency"],
|
||||
["php", "webLivePhpCapacity"], ["bytes", "webLiveBytes"]]) {
|
||||
const item = el("div");
|
||||
const name = el("small", t(key));
|
||||
name.dataset.i18n = key;
|
||||
const value = el("strong", "-"); value.dataset.webLiveField = field;
|
||||
item.append(name, value); figures.append(item);
|
||||
}
|
||||
const chart = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
chart.setAttribute("viewBox", "0 0 300 60"); chart.setAttribute("role", "img");
|
||||
chart.setAttribute("aria-label", t("webLiveRate"));
|
||||
const line = document.createElementNS("http://www.w3.org/2000/svg", "polyline");
|
||||
line.setAttribute("points", "0,55 300,55"); chart.append(line);
|
||||
const split = el("p", "-", "www-service-split"); split.dataset.webLiveField = "split";
|
||||
panel.append(figures, chart, split); live.append(panel);
|
||||
live.addEventListener("toggle", () => { if (live.open && latestStatus) renderLive(latestStatus, false); });
|
||||
box.append(details, live); return box;
|
||||
});
|
||||
$("web-service-list").replaceChildren(...(cards.length ? cards : [el("p", t(query ? "webServiceSearchEmpty" : "webServiceEmpty"), "fine")]));
|
||||
}
|
||||
|
||||
const serviceHistory = new Map();
|
||||
const serviceLast = new Map();
|
||||
function renderLive(status, record = true) {
|
||||
if (currentPanel !== "web-server") return;
|
||||
const services = status?.web_server_metrics || {};
|
||||
for (const panel of document.querySelectorAll("#web-service-list [data-web-live-id]")) {
|
||||
if (!panel.closest("details")?.open) continue;
|
||||
const id = panel.dataset.webLiveId, values = services[id], web = values?.web;
|
||||
const lookup = key => panel.querySelector(`[data-web-live-field="${key}"]`);
|
||||
const set = (key, value) => { const node = lookup(key); if (node) node.textContent = value; };
|
||||
if (!web) { for (const key of ["requests", "rate", "errors", "latency", "php", "bytes", "split"]) set(key, "-"); continue; }
|
||||
const n = value => value == null || !Number.isFinite(Number(value)) ? 0 : Number(value);
|
||||
const total = n(web.requests), php = values.php, last = serviceLast.get(id);
|
||||
const sample = rustProxyRateSampling.difference(record ? last : null,
|
||||
[total, n(web.response_headers_us), n(web.status_5xx)], performance.now(),
|
||||
rustProxyRateSampling.cadence("overview_seconds"));
|
||||
if (record) serviceLast.set(id, sample.next);
|
||||
const deltas = record ? sample.deltas : null;
|
||||
const rate = deltas ? deltas[0] / sample.seconds : null;
|
||||
const previous = serviceHistory.get(id) || [];
|
||||
if (record) { previous.push(rate); window.rustProxyOverviewSamples.trim(previous); serviceHistory.set(id, previous); }
|
||||
const peak = Math.max(1, ...previous.filter(x => x != null));
|
||||
const points = previous.map((value, i) => `${300 * i / Math.max(1, previous.length - 1)},${55 - (value || 0) / peak * 50}`).join(" ");
|
||||
panel.querySelector("polyline")?.setAttribute("points", points || "0,55 300,55");
|
||||
set("requests", fmt(total)); set("rate", rate == null ? "-" : `${fmt(rate, 1)}/s`);
|
||||
set("errors", fmt(n(web.status_5xx)));
|
||||
set("latency", deltas?.[0] > 0 ? `${fmt(deltas[1] / deltas[0] / 1000, 1)} ms` : "-");
|
||||
set("php", php ? `${fmt(n(php.capacity_used))} / ${fmt(n(php.capacity_limit))}` : t("webLiveNoPhp"));
|
||||
set("bytes", fmtBytes(n(web.response_bytes)));
|
||||
set("split", `${t("webLiveKinds")}: ${fmt(n(web.static_requests))} / ${fmt(n(web.php_requests))} / ${fmt(n(web.other_requests))}`);
|
||||
}
|
||||
}
|
||||
window.rustProxyOverviewSamples.onChange(() => {
|
||||
for (const history of serviceHistory.values()) window.rustProxyOverviewSamples.trim(history);
|
||||
if (latestStatus && currentPanel === "web-server") renderLive(latestStatus, false);
|
||||
});
|
||||
|
||||
form.addEventListener("submit", async event => {
|
||||
event.preventDefault(); if (!envelope || busy) return;
|
||||
const invalid = [...form.elements].find(input => input.willValidate && !input.checkValidity()); if (invalid) { activateTab(invalid.closest("[data-web-service-page]")?.dataset.webServicePage || "general"); invalid.reportValidity(); return; }
|
||||
@@ -491,6 +550,6 @@
|
||||
$("web-service-search").addEventListener("input", render);
|
||||
dialog.addEventListener("cancel", event => { event.preventDefault(); closeEditor(); });
|
||||
window.rustProxyDrafts.register("web-server", { labelKey: "webServer", isOpen: () => dialog.open, isDirty: () => dirty, suspend: suspendDraft, restore: restoreDraft, close: clearEditor });
|
||||
window.rustProxyWebServer = { render, reset: clearEditor };
|
||||
window.rustProxyWebServer = { render, renderLive, reset() { clearEditor(); serviceHistory.clear(); serviceLast.clear(); } };
|
||||
if (envelope) render();
|
||||
})();
|
||||
Reference in new issue
Block a user