summaryrefslogtreecommitdiffstats
path: root/assets/index.js
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2024-09-26 17:31:16 -0500
committerToby Vincent <tobyv@tobyvin.dev>2024-09-26 17:31:16 -0500
commitfd992d7e3c03f37fbcafe9d3f26c72a2ead3b2a7 (patch)
treef3e29427d1bbe4a8d6e050abbd9f66afb5fa2152 /assets/index.js
parentcbfca14b38806798847e3f2008038b25194a9b8b (diff)
feat!: impl full api
Diffstat (limited to 'assets/index.js')
-rw-r--r--assets/index.js87
1 files changed, 87 insertions, 0 deletions
diff --git a/assets/index.js b/assets/index.js
new file mode 100644
index 0000000..173ed72
--- /dev/null
+++ b/assets/index.js
@@ -0,0 +1,87 @@
+/**
+ * @typedef {Object} Check
+ * @property {String} status - 'pass'|'fail'|'warn'
+ * @property {String} output - Details. Not present if 'pass'
+ */
+
+/**
+ * @typedef {Check} HealthCheck
+ * @property {Map<String, Check>} 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} issues detected`;
+ statusElm.setAttribute("class", "error");
+ break;
+ case "warn":
+ issuesElm.textContent = `${check.output} warnings detected`;
+ 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;
+ });
+ }
+});