v0.32.2
This commit is contained in:
1 parent
bb025dcf44
commit
b0f211555a
74 files changed
+6089
-556
No files matched your search
@@ -0,0 +1,106 @@
|
||||
window.rustProxyWideOverview = (() => {
|
||||
const limit = 60;
|
||||
const configurations = {
|
||||
wide_protocol_rates: {
|
||||
unit: "rate", names: ["h1", "h2", "h3"], counters: s =>
|
||||
[s.metrics?.http1_requests, s.metrics?.http2_requests, s.metrics?.http3_requests]
|
||||
},
|
||||
wide_cpu: {
|
||||
unit: "percent", names: ["system", "process"], values: s =>
|
||||
[s.system?.cpu_percent, s.system?.process_cpu_percent]
|
||||
},
|
||||
wide_memory: {
|
||||
unit: "bytes", names: ["process", "cache"], values: s =>
|
||||
[s.system?.process_rss_bytes, s.cache?.resident_bytes]
|
||||
},
|
||||
wide_cache_activity: {
|
||||
unit: "rate", names: ["hits", "misses"], counters: s =>
|
||||
[s.cache?.hits, s.cache?.misses]
|
||||
},
|
||||
wide_connections: {
|
||||
unit: "count", names: ["open", "websockets"], values: s =>
|
||||
[s.metrics?.active_connections, s.metrics?.websocket_active]
|
||||
},
|
||||
wide_backend_health: {
|
||||
unit: "count", names: ["up", "down"], values: s => {
|
||||
if (!Array.isArray(s.backend_pools)) return [null, null];
|
||||
const members = s.backend_pools.flatMap(pool => pool.members || []);
|
||||
return [members.filter(m => m.status === "up").length, members.filter(m => m.status === "down").length];
|
||||
}
|
||||
},
|
||||
wide_latency: {
|
||||
unit: "ms", names: ["response", "probe"], values: s => {
|
||||
if (!Array.isArray(s.backend_pools)) return [s.metrics?.mean_duration_ms, null];
|
||||
const members = s.backend_pools.flatMap(pool => pool.members || []);
|
||||
const probes = members.filter(m => m.status === "up" && m.health_mode !== "off"
|
||||
&& finite(m.last_probe_ms) !== null && finite(m.latency_ms) !== null
|
||||
&& Number(m.last_probe_ms) > 0);
|
||||
return [s.metrics?.mean_duration_ms,
|
||||
probes.length ? probes.reduce((total, m) => total + Number(m.latency_ms), 0) / probes.length : null];
|
||||
}
|
||||
},
|
||||
};
|
||||
const history = new Map(), baselines = new Map(), last = new Map();
|
||||
let revision = null;
|
||||
const finite = value => value != null && Number.isFinite(Number(value)) && Number(value) >= 0 ? Number(value) : null;
|
||||
const format = (n, unit) => n === null ? "-" : unit === "bytes" ? fmtBytes(n)
|
||||
: unit === "percent" ? `${fmt(n, 1)}%` : unit === "ms" ? `${fmt(n, 1)} ms`
|
||||
: unit === "rate" ? `${fmt(n, 1)}/s` : fmt(n);
|
||||
const tile = id => document.querySelector(`[data-dashboard-widget="${id}"]`);
|
||||
function counterRates(id, values, now, record) {
|
||||
const counters = values.map(finite);
|
||||
if (counters.some(n => n === null)) { baselines.delete(id); return counters.map(() => null); }
|
||||
if (!record) return last.get(id) || counters.map(() => null);
|
||||
const previous = baselines.get(id);
|
||||
baselines.set(id, { counters, now });
|
||||
if (!previous || now <= previous.now || counters.some((n, i) => n < previous.counters[i]))
|
||||
return counters.map(() => null);
|
||||
const elapsed = (now - previous.now) / 1000;
|
||||
return counters.map((n, i) => (n - previous.counters[i]) / elapsed);
|
||||
}
|
||||
function path(values, peak) {
|
||||
const count = values.length;
|
||||
let result = "", drawing = false;
|
||||
for (let i = 0; i < count; i++) {
|
||||
const value = values[i];
|
||||
if (value === null) { drawing = false; continue; }
|
||||
const x = Math.round(600 * i / Math.max(1, count - 1));
|
||||
const y = Math.round(137 - 120 * value / peak);
|
||||
result += `${drawing ? " L" : " M"}${x} ${y}`;
|
||||
drawing = true;
|
||||
}
|
||||
return result.trim();
|
||||
}
|
||||
function render(status, record = true) {
|
||||
if (!status || currentPanel !== "overview") return;
|
||||
if (revision !== status.revision) { reset(); revision = status.revision; }
|
||||
const now = performance.now();
|
||||
for (const [id, config] of Object.entries(configurations)) {
|
||||
const node = tile(id);
|
||||
if (!node || node.hidden) { baselines.delete(id); continue; }
|
||||
const values = config.counters ? counterRates(id, config.counters(status), now, record)
|
||||
: config.values(status).map(finite);
|
||||
const series = history.get(id) || config.names.map(() => []);
|
||||
if (record) {
|
||||
values.forEach((value, i) => {
|
||||
series[i].push(value);
|
||||
if (series[i].length > limit) series[i].shift();
|
||||
});
|
||||
history.set(id, series);
|
||||
last.set(id, values);
|
||||
}
|
||||
const peak = Math.max(config.unit === "percent" ? 100 : 1,
|
||||
...series.flat().filter(n => n !== null));
|
||||
config.names.forEach((key, i) => {
|
||||
const value = values[i];
|
||||
const field = $(`overview-wide-${id}-${key}-value`);
|
||||
if (field) field.textContent = format(value, config.unit);
|
||||
$(`overview-wide-${id}-${key}-line`)?.setAttribute("d", path(series[i], peak));
|
||||
});
|
||||
const summary = $(`overview-wide-${id}-summary`);
|
||||
if (summary) summary.textContent = format(values[0], config.unit);
|
||||
}
|
||||
}
|
||||
function reset() { history.clear(); baselines.clear(); last.clear(); revision = null; }
|
||||
return { render, reset };
|
||||
})();
|
||||
Reference in new issue
Block a user