Add automatic health checks and status indicators for services

This commit is contained in:
MayaChat
2025-11-24 00:03:14 -05:00
parent f14955e534
commit 5c798c075d
4 changed files with 92 additions and 24 deletions

View File

@@ -54,7 +54,8 @@
const port = s.getAttribute('port') || '';
const logo = s.getAttribute('logo') || '';
const hostAttr = s.getAttribute('host'); // optional public hostname or full URL
const status = s.getAttribute('status'); // optional: 'online', 'offline', 'maintenance'
const manualStatus = s.getAttribute('status'); // optional: 'online', 'offline', 'maintenance'
const checkHealth = s.getAttribute('check-health') !== 'false'; // default true, set to false to disable
// Build href: prefer explicit host attribute when present.
// Rules:
@@ -102,11 +103,54 @@
a.appendChild(img);
a.appendChild(span);
// Add status indicator if status attribute is set
if(status){
const statusDot = document.createElement('span');
statusDot.className = `status-dot status-${status}`;
statusDot.title = `Status: ${status}`;
// Add status indicator - will be updated by health check
const statusDot = document.createElement('span');
statusDot.className = 'status-dot status-checking';
statusDot.title = 'Checking status...';
let currentStatus = 'checking';
// If maintenance mode is set manually, use that and skip health check
if(manualStatus === 'maintenance'){
statusDot.className = 'status-dot status-maintenance';
statusDot.title = 'Status: maintenance';
currentStatus = 'maintenance';
a.appendChild(statusDot);
} else if(checkHealth && href){
// Show checking indicator initially
a.appendChild(statusDot);
// Perform health check
(async function performHealthCheck(){
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 second timeout
const response = await fetch(href, {
method: 'HEAD',
mode: 'no-cors', // Allow cross-origin requests
cache: 'no-cache',
signal: controller.signal
});
clearTimeout(timeoutId);
// In no-cors mode, opaque responses mean the server responded
// We consider this as "online"
currentStatus = 'online';
statusDot.className = 'status-dot status-online';
statusDot.title = 'Status: online';
} catch(err) {
// Connection failed or timed out
currentStatus = 'offline';
statusDot.className = 'status-dot status-offline';
statusDot.title = 'Status: offline';
}
})();
} else if(manualStatus){
// Use manual status if health check is disabled
statusDot.className = `status-dot status-${manualStatus}`;
statusDot.title = `Status: ${manualStatus}`;
currentStatus = manualStatus;
a.appendChild(statusDot);
}