/** * @typedef {Object} Check * @property {String} status - 'pass'|'fail'|'warn' * @property {String} output - Details. Not present if 'pass' */ /** * @typedef {Check} HealthCheck * @property {Map} checks */ async function getHealthCheck() { const url = "api/healthcheck"; try { const response = await fetch(url); if (!response.ok) { throw new Error(`Response status: ${response.status}`); } const json = await response.json(); return json; } catch (error) { console.error(error.message); } } function updateStatus(check) { const statusElm = document.getElementById("status"); const issuesElm = document.getElementById("issues"); switch (check.status) { case "pass": issuesElm.textContent = "No issues detected"; statusElm.setAttribute("class", "ok"); break; case "fail": issuesElm.textContent = check.output; statusElm.setAttribute("class", "error"); break; case "warn": issuesElm.textContent = check.output; statusElm.setAttribute("class", "warning"); break; default: issuesElm.textContent = "Unknown"; statusElm.setAttribute("class", "warning"); } } getHealthCheck().then((healthCheck) => { const table = document.getElementById("services"); const evtSource = new EventSource("sse"); updateStatus(healthCheck); for (const [service, check] of Object.entries(healthCheck.checks)) { const row = table.insertRow(); const nameNode = row.insertCell(); nameNode.textContent = service; const stateNode = row.insertCell(); switch (check.status) { case "pass": stateNode.textContent = "Operational"; stateNode.setAttribute("class", "ok"); break; case "fail": stateNode.textContent = "Down"; stateNode.title = check.output; stateNode.setAttribute("class", "error"); break; case "warn": stateNode.textContent = "Warning"; stateNode.title = check.output; stateNode.setAttribute("class", "warning"); break; default: stateNode.textContent = "Unknown"; statusElm.setAttribute("class", "warning"); } evtSource.addEventListener(service, (event) => { const status = JSON.parse(event.data); stateNode.textContent = status.state; stateNode.title = status.output; }); } });