feat: render RTT history chart per connection in Connectivity section
This commit is contained in:
@@ -445,8 +445,12 @@
|
|||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
if (data.connections && data.connections.length) {
|
if (data.connections && data.connections.length) {
|
||||||
html += `<div class="info-thresholds-title">Connectivity</div>
|
html += `<div class="info-thresholds-title">Connectivity</div>`;
|
||||||
<table class="data-table"><thead><tr>
|
for (const c of data.connections) {
|
||||||
|
html += `<div class="info-note">${escHtml(c.family)} · ${escHtml(c.addr || '—')} RTT</div>
|
||||||
|
<div id="rtt-chart-${hostname}-${escHtml(c.family)}" style="margin-bottom:8px;"></div>`;
|
||||||
|
}
|
||||||
|
html += `<table class="data-table"><thead><tr>
|
||||||
<th>Family</th><th>Address</th><th>State</th>
|
<th>Family</th><th>Address</th><th>State</th>
|
||||||
<th class="num">RTT</th><th>Last Change</th><th>Last Packet</th>
|
<th class="num">RTT</th><th>Last Change</th><th>Last Packet</th>
|
||||||
</tr></thead><tbody>`;
|
</tr></thead><tbody>`;
|
||||||
@@ -495,6 +499,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
el.innerHTML = html;
|
el.innerHTML = html;
|
||||||
|
|
||||||
|
if (data.connections && data.connections.length) {
|
||||||
|
const rttThresholds = (data.thresholds || []).find(t => t.metric === 'rtt') || null;
|
||||||
|
for (const c of data.connections) {
|
||||||
|
fetchRttHistory(hostname, c.family)
|
||||||
|
.then(samples => renderRttChart(hostname, c.family, samples, rttThresholds))
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchHostGlance(hostname) {
|
async function fetchHostGlance(hostname) {
|
||||||
@@ -899,6 +912,35 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchRttHistory(hostname, family) {
|
||||||
|
const plugin = `rtt_${family.toLowerCase()}`;
|
||||||
|
const r = await fetch(`/api/0/hosts/${encodeURIComponent(hostname)}/plugins/${plugin}?limit=100`);
|
||||||
|
if (!r.ok) return [];
|
||||||
|
const json = await r.json();
|
||||||
|
return json.samples || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderRttChart(hostname, family, samples, rttThresholds) {
|
||||||
|
const pts = samples
|
||||||
|
.filter(s => s.data.rtt != null && s.data.rtt > 0)
|
||||||
|
.map(s => ({ t: s.timestamp, v: s.data.rtt }));
|
||||||
|
|
||||||
|
renderTimeSeriesChart(`rtt-chart-${hostname}-${family}`, pts, {
|
||||||
|
yDomain: 'auto',
|
||||||
|
clipId: `rtt-clip-${hostname}-${family}`,
|
||||||
|
unitSuffix: ' ms',
|
||||||
|
colorFor: (latest) => {
|
||||||
|
if (rttThresholds?.critical != null && latest > rttThresholds.critical) {
|
||||||
|
return { stroke: '#e53935', fill: '#ffcdd2' };
|
||||||
|
}
|
||||||
|
if (rttThresholds?.warning != null && latest > rttThresholds.warning) {
|
||||||
|
return { stroke: '#fb8c00', fill: '#ffe0b2' };
|
||||||
|
}
|
||||||
|
return { stroke: '#1976d2', fill: '#bbdefb' };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function renderCpuTable(hostname, d) {
|
function renderCpuTable(hostname, d) {
|
||||||
const KEYS = [
|
const KEYS = [
|
||||||
['cpu_percent', 'CPU Usage', 'bar'],
|
['cpu_percent', 'CPU Usage', 'bar'],
|
||||||
|
|||||||
Reference in New Issue
Block a user