diff --git a/pb_hooks/status.pb.js b/pb_hooks/status.pb.js index 420b879..60fd29c 100644 --- a/pb_hooks/status.pb.js +++ b/pb_hooks/status.pb.js @@ -195,7 +195,8 @@ routerAdd("GET", "/api/status", (e) => { // Upstream liveness rides along on the same call rather than a // second round trip: it is produced by the same service and read // by the same screen. - upstreams: stats.upstreams } + upstreams: stats.upstreams, + throughput: stats.throughput } }) return e.json(200, { diff --git a/pb_public/status.html b/pb_public/status.html index bd0deb6..97a8a74 100644 --- a/pb_public/status.html +++ b/pb_public/status.html @@ -417,6 +417,33 @@ function sinceLabel(unix){ ("0" + d.getMinutes()).slice(-2); } +// Whose bytes were slow. Not a ranking input and deliberately not per file: a +// stall is a property of neither the upload nor the hostname, because TorBox +// hands out CDN nodes per request. This exists to answer "was it them or us" +// for a person looking at a screen, which is the question that took an evening +// of measurement the first time it was asked. +function panelThroughput(a){ + var t = a && a.throughput; + if (!t || !t.length) return ""; + var rows = t.map(function(x){ + // Mbit/s reads the way a person thinks about a connection; kbps does not. + var med = (x.medianKbps / 1000).toFixed(1); + var worst = x.worstMinKbps === null ? "—" : (x.worstMinKbps / 1000).toFixed(1); + // Time spent waiting is the number that matches what the viewer felt. + var stall = x.stalledPct === null ? "—" : x.stalledPct + " %"; + var bad = x.stalledPct !== null && x.stalledPct >= 2; + return "" + esc(x.provider) + '' + x.sessions + + '' + med + '' + worst + + '" + stall + + ""; + }).join(""); + return '

Rychlost zdrojů za 24 h

' + + '' + + '' + rows + + '
poskytovatelrelacímedián Mb/snejhorší propadčekání

Medián, ne průměr: jedna rychlá relace nemá schovat deset pomalých. ' + + "Sloupec čekání je podíl sledovaného času stráveného načítáním.

"; +} + function panelAccounts(a){ if (!a || a.error) return ""; return '

Účty

' + @@ -1191,7 +1218,7 @@ async function load(){ el("main").innerHTML = panelServices(d.coolify) + panelReleases(d.releases) + panelClients(d.clients) + panelApi(d.amberApi) + panelAccounts(d.accounts) + - panelUpstreams(d.amberApi) + + panelUpstreams(d.amberApi) + panelThroughput(d.amberApi) + panelErrors(errs); wire(); } catch (e) {