diff --git a/static/client.js b/static/client.js index 777012f..e12a953 100644 --- a/static/client.js +++ b/static/client.js @@ -1,4 +1,5 @@ let config; +let lastPulse = 0; document.addEventListener("DOMContentLoaded", async () => { let $main = document.querySelector('main'); const refreshStatus = async () => { @@ -10,6 +11,7 @@ document.addEventListener("DOMContentLoaded", async () => { const status = await response.json(); $main.innerHTML = ''; config = status.config; + lastPulse = status.lastPulse; for (let [siteId, endpointIds] of status.ui) { let site = status.sites[siteId]; if(!site) @@ -21,15 +23,15 @@ document.addEventListener("DOMContentLoaded", async () => { $siteName.innerText = site.name; $site.append($siteName); - let $statusBar = document.createElement('status-bar'); - $statusBar.logs = ''; - $site.append($statusBar); $main.append($site); + let nEndpoints = 0; + let endpointPoints = []; for (let endpointId of endpointIds) { let endpoint = site.endpoints[endpointId]; if(!endpoint) continue; + nEndpoints++; let $endpoint = document.createElement('div'); $endpoint.classList.add('endpoint'); @@ -38,11 +40,27 @@ document.addEventListener("DOMContentLoaded", async () => { $endpoint.append($endpointName); let $statusBarEndpoint = document.createElement('status-bar'); - $statusBarEndpoint.logs = endpoint.logs; + endpointPoints.push($statusBarEndpoint.setLogs(endpoint.logs)); $endpoint.append($statusBarEndpoint); $site.append($endpoint); } + if(nEndpoints>1) { + let $statusBar = document.createElement('status-bar'); + let combinedLogs = []; + for(let i=0;ip[i]?.t).filter(p=>p)); + let err = endpointPoints.map(p=>p[i]?.err).filter(p=>p).join("\n") || undefined; + let ttfb = Math.max(...endpointPoints.map(p=>p[i]?.ttfb).filter(p=>p)); + let dur = Math.max(...endpointPoints.map(p=>p[i]?.dur).filter(p=>p)); + let dns = Math.max(...endpointPoints.map(p=>p[i]?.dns).filter(p=>p)); + let tcp = Math.max(...endpointPoints.map(p=>p[i]?.tcp).filter(p=>p)); + combinedLogs.push({t, err, ttfb, dur, dns, tcp}); + } + console.log(combinedLogs); + $statusBar.setLogs(combinedLogs); + $site.querySelector('h1').after($statusBar); + } } } catch (error) { console.error("Error loading server status:", error); @@ -75,14 +93,14 @@ class StatusBar extends HTMLElement { constructor() { super(); } - - set logs(logs) { + setLogs(logs) { this.innerHTML = ''; - this.logs_ = logs; - let now = Date.now(); - for(let i=config.nDataPoints;i>0;i--) { - let date = now - i * config.interval * 60_000; + this.logs = logs; + let points = []; + for(let i=config.nDataPoints-1;i>=0;i--) { + let date = lastPulse - i * config.interval * 60_000; let point = findClosestPoint(logs, date, config.interval * 60_000/2); + points.push(point); const $entry = document.createElement('status-bar-entry'); $entry.setAttribute('tabindex', 0); if(point) { @@ -90,26 +108,28 @@ class StatusBar extends HTMLElement { ${formatDate(point.t)} `; + let status; if(point.err) { - $entry.setAttribute('data-status', 'outage'); - $entry.querySelector('em').innerText = point.err; + status = 'outage'; + $entry.querySelector('em').before(point.err); } else { - if(point.dur > config.responseTimeWarning) { - $entry.setAttribute('data-status', 'highly-degraded'); - } else if(point.dur > config.responseTimeGood) { - $entry.setAttribute('data-status', 'degraded'); + if(point.ttfb > config.responseTimeWarning) { + status = 'highly-degraded'; + } else if(point.ttfb > config.responseTimeGood) { + status = 'degraded'; } else { - $entry.setAttribute('data-status', 'healthy'); + status = 'healthy'; } } + $entry.setAttribute('data-status', status); $entry.querySelector('em').innerText = `Latency: ${point.ttfb.toFixed(2)}ms`; } else { $entry.setAttribute('data-status', 'none'); $entry.innerHTML = `
No Data
`; } this.append($entry); - } + return points; } } customElements.define('status-bar', StatusBar);