summaryrefslogtreecommitdiffstats
path: root/assets/index.js
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2024-09-28 00:54:46 -0500
committerToby Vincent <tobyv@tobyvin.dev>2024-09-28 00:58:45 -0500
commitcd774827dd14f68d8405c45d2d9da30b3fab050e (patch)
treea24e1cabb99170caa25edff53fc978111a1c9dd4 /assets/index.js
parent04c7f7609e5bc3fadf95c53b37a9e6e12c4e539c (diff)
feat: refactor into pub-sub and impl SSE
Diffstat (limited to 'assets/index.js')
-rw-r--r--assets/index.js92
1 files changed, 37 insertions, 55 deletions
diff --git a/assets/index.js b/assets/index.js
index 246364f..e65369c 100644
--- a/assets/index.js
+++ b/assets/index.js
@@ -1,16 +1,7 @@
-/**
- * @typedef {Object} Check
- * @property {String} status - 'pass'|'fail'|'warn'
- * @property {String} output - Details. Not present if 'pass'
- */
+const serviceMap = new Map();
-/**
- * @typedef {Check} HealthCheck
- * @property {Map<String, Check>} checks
- */
-
-async function getHealthCheck() {
- const url = "api/healthcheck";
+async function getServices() {
+ const url = "api/services";
try {
const response = await fetch(url);
if (!response.ok) {
@@ -24,64 +15,55 @@ async function getHealthCheck() {
}
}
-function updateStatus(check) {
+function updateStatus() {
const statusElm = document.getElementById("status");
const issuesElm = document.getElementById("issues");
- switch (check.status) {
+ const issues = [...serviceMap.values()].filter((s) => !s).length;
+ issuesElm.textContent = `${issues} issue(s) detected`;
+ if (issues) {
+ statusElm.setAttribute("class", "error");
+ } else {
+ statusElm.setAttribute("class", "ok");
+ }
+}
+
+function updateService(name, node, status) {
+ switch (status.status) {
case "pass":
- issuesElm.textContent = "No issues detected";
- statusElm.setAttribute("class", "ok");
+ node.textContent = "Operational";
+ node.setAttribute("class", "ok");
break;
case "fail":
- issuesElm.textContent = check.output;
- statusElm.setAttribute("class", "error");
+ node.textContent = "Down";
+ node.title = status.output;
+ node.setAttribute("class", "error");
break;
case "warn":
- issuesElm.textContent = check.output;
- statusElm.setAttribute("class", "warning");
+ node.textContent = "Warning";
+ node.title = status.output;
+ node.setAttribute("class", "warning");
break;
- default:
- issuesElm.textContent = "Unknown";
- statusElm.setAttribute("class", "warning");
+ case "unknown":
+ node.textContent = "Unknown";
+ node.setAttribute("class", "warning");
}
-}
-getHealthCheck().then((healthCheck) => {
- const table = document.getElementById("services");
- const evtSource = new EventSource("sse");
- updateStatus(healthCheck);
+ serviceMap.set(name, status.status === "pass");
+ updateStatus();
+}
- for (const [service, check] of Object.entries(healthCheck.checks)) {
+getServices().then((services) => {
+ for (const [service] of Object.entries(services)) {
+ const table = document.getElementById("services");
const row = table.insertRow();
-
const nameNode = row.insertCell();
nameNode.textContent = service;
+ const node = row.insertCell();
- 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 evtSource = new EventSource(`sse/${service}`);
+ evtSource.onmessage = (event) => {
const status = JSON.parse(event.data);
- stateNode.textContent = status.state;
- stateNode.title = status.output;
- });
+ updateService(service, node, status);
+ };
}
});