Add automatic health checks and status indicators for services
This commit is contained in:
56
index.html
56
index.html
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user