another huge bugfix push, working releast
This commit is contained in:
@ -155,8 +155,8 @@ if (!in_array($mode, $validModes, true)) {
|
||||
/* ---------- API configuration per mode ---------- */
|
||||
$apiConfig = [
|
||||
'cosmostat' => ['bind' => '10.200.27.20', 'port' => '5000'],
|
||||
/*'gali' => ['bind' => '10.200.27.20', 'port' => '5000'], // same as cosmostat*/
|
||||
'drive_health' => ['bind' => '172.25.1.18', 'port' => '5001'], // new API
|
||||
/*'gali' => ['bind' => '10.200.27.20', 'port' => '5000'], // space filler */
|
||||
'drive_health' => ['bind' => '0.0.0.0', 'port' => '5001'], // drive health API
|
||||
];
|
||||
|
||||
/* ---------- Helper: fetch client details ---------- */
|
||||
@ -251,7 +251,7 @@ function renderSidebar(string $mode){
|
||||
?>
|
||||
<nav class="sidebar">
|
||||
<form method="get" id="modeForm">
|
||||
<label for="modeSelect">Mode:</label>
|
||||
<label for="modeSelect"></label>
|
||||
<select class="select-dark" name="mode" id="modeSelect" onchange="this.form.submit()">
|
||||
<?php foreach ($modes as $key => $label): ?><option value="<?= h($key) ?>" <?= $mode === $key ? 'selected' : '' ?>><?= h($label) ?></option>
|
||||
<?php endforeach; ?></select>
|
||||
@ -297,6 +297,13 @@ function renderSidebar(string $mode){
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($mode == 'cosmostat'): ?>
|
||||
|
||||
<input type="hidden" name="host" value="<?= h($selectedId) ?>">
|
||||
<h3>Endpoints</h3>
|
||||
<ol id="endpointList"></ol>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($mode == 'gali'): ?>
|
||||
<h3>Shuttle Gali</h3>
|
||||
<?php endif; ?>
|
||||
@ -473,7 +480,6 @@ function renderMainContent(string $mode){
|
||||
|
||||
</div> <!-- /wrapper -->
|
||||
|
||||
<?php if ($mode != 'drive_health'): ?>
|
||||
<!-- cosmostat javascript -->
|
||||
<script src="socket.io/socket.io.js"></script>
|
||||
<script src="src/system_metrics.js"></script>
|
||||
@ -488,9 +494,7 @@ function renderMainContent(string $mode){
|
||||
help.style.display = help.style.display === 'none' || help.style.display === '' ? 'block' : 'none';
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($mode == 'drive_health'): ?>
|
||||
<!-- drive health javascript -->
|
||||
<script>
|
||||
// Removal Handler
|
||||
@ -503,7 +507,6 @@ function renderMainContent(string $mode){
|
||||
document.getElementById('remove_hosts_input').value = ids.join(',');
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -61,13 +61,17 @@ a:hover { text-decoration: underline; }
|
||||
/* optional: keep it above other content */
|
||||
z-index: 1000;
|
||||
}
|
||||
.sidebar h3 { margin: 0 0 .4rem 0; font-size: 1.1rem; }
|
||||
.sidebar h3 { margin: 0 0 .4rem 0; font-size: 1.3rem; }
|
||||
.sidebar ul { list-style: none; padding: 0; margin: 0; }
|
||||
.sidebar ol { list-style: none; padding: 0; margin: 0; }
|
||||
.sidebar li { margin-bottom: .4rem; }
|
||||
.sidebar li { margin-bottom: .4rem; font-size: 1.1rem; }
|
||||
.sidebar a { color: var(--clr-accent); }
|
||||
.sidebar a.active { font-weight: bold; }
|
||||
/*
|
||||
.endpointList {
|
||||
|
||||
}
|
||||
*/
|
||||
.main{
|
||||
flex: 1;
|
||||
padding: 1rem;
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
/* ==============================================================
|
||||
system_metrics.js
|
||||
============================================================== */
|
||||
/* system_metrics.js */
|
||||
|
||||
(() => {
|
||||
/* ==========================================================
|
||||
Socket.IO setup
|
||||
========================================================== */
|
||||
/* Socket.IO setup */
|
||||
const socket = io({
|
||||
transports: ['websocket', 'polling'],
|
||||
reconnection: true,
|
||||
@ -15,15 +12,11 @@
|
||||
pingTimeout: 5000,
|
||||
pingInterval: 25000,
|
||||
});
|
||||
/* ==========================================================
|
||||
Color constants
|
||||
========================================================== */
|
||||
/* Color constants */
|
||||
const GREEN = [ 39, 174, 96]; // #27ae60
|
||||
const YELLOW = [243, 156, 18]; // #f39c12
|
||||
const RED = [192, 57, 43]; // #c0392b
|
||||
/* ==========================================================
|
||||
Helpers
|
||||
========================================================== */
|
||||
/* Helpers */
|
||||
const hostTimestamps = {}; // keyed by short_id
|
||||
const toRgb = (r, g, b) => `rgb(${r},${g},${b})`;
|
||||
const T20 = 20 * 1000;
|
||||
@ -53,15 +46,11 @@
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = txt;
|
||||
}
|
||||
/* ==========================================================
|
||||
Get the short_id from the query string
|
||||
========================================================== */
|
||||
/* Get the short_id from the query string */
|
||||
function getSelectedId() {
|
||||
return new URLSearchParams(window.location.search).get('host') || '';
|
||||
}
|
||||
/* ==========================================================
|
||||
Sidebar building - uses short_id for status key
|
||||
========================================================== */
|
||||
/* Sidebar building - uses short_id for status key */
|
||||
|
||||
function buildList(systemList) {
|
||||
const ul = document.getElementById('endpointList');
|
||||
@ -71,9 +60,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
/* ────────────────────────────────────────
|
||||
* Sort: servers first, then by IP
|
||||
* ──────────────────────────────────────── */
|
||||
/* Sort: servers first, then by IP */
|
||||
const toInt = ip => {
|
||||
// guard against undefined / empty string
|
||||
if (!ip) return 0;
|
||||
@ -81,12 +68,12 @@
|
||||
};
|
||||
|
||||
const sorted = [...systemList].sort((a, b) => {
|
||||
// a. Servers go before non‑servers
|
||||
// a. Servers go before non-servers
|
||||
const aServer = !!a.is_server;
|
||||
const bServer = !!b.is_server;
|
||||
if (aServer !== bServer) return aServer ? -1 : 1; // true < false
|
||||
|
||||
// b. Same “is_server” status – fall back to IP sorting
|
||||
// b. Same “is_server” status - fall back to IP sorting
|
||||
const aIp = a.active_ip ?? '';
|
||||
const bIp = b.active_ip ?? '';
|
||||
|
||||
@ -96,16 +83,12 @@
|
||||
return toInt(aIp) - toInt(bIp);
|
||||
});
|
||||
|
||||
/* ────────────────────────────────────────
|
||||
* Bail if nothing actually changed
|
||||
* ──────────────────────────────────────── */
|
||||
/* Bail if nothing actually changed */
|
||||
const current = Array.from(ul.children).map(li => li.dataset.id);
|
||||
const newIds = sorted.map(s => s.short_id);
|
||||
if (arraysEqual(current, newIds)) return; // no visual change needed
|
||||
|
||||
/* ────────────────────────────────────────
|
||||
* Build the DOM
|
||||
* ──────────────────────────────────────── */
|
||||
/* Build the DOM */
|
||||
const selected = getSelectedId().toLowerCase();
|
||||
ul.innerHTML = ''; // reset
|
||||
|
||||
@ -117,7 +100,7 @@
|
||||
status.className = 'host-status';
|
||||
status.dataset.id = item.short_id;
|
||||
|
||||
// • Link – display hostname, encode short_id in URL
|
||||
// • Link - display hostname, encode short_id in URL
|
||||
const a = document.createElement('a');
|
||||
a.href = '?host=' + encodeURIComponent(item.short_id);
|
||||
a.textContent = item.hostname;
|
||||
@ -130,9 +113,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Update status colors every second
|
||||
========================================================== */
|
||||
/* Update status colors every second */
|
||||
function updateStatusColors() {
|
||||
const nowSec = Date.now() / 1000;
|
||||
Object.entries(hostTimestamps).forEach(([id, ts]) => {
|
||||
@ -145,9 +126,7 @@
|
||||
});
|
||||
}
|
||||
setInterval(updateStatusColors, 1000);
|
||||
/* ==========================================================
|
||||
Utility helpers
|
||||
========================================================== */
|
||||
/* Utility helpers */
|
||||
function arraysEqual(a, b) {
|
||||
if (a.length !== b.length) return false;
|
||||
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
||||
@ -225,9 +204,7 @@
|
||||
});
|
||||
return table;
|
||||
}
|
||||
/* ==========================================================
|
||||
Handle incoming data
|
||||
========================================================== */
|
||||
/* Handle incoming data */
|
||||
let lastUpdate = Date.now();
|
||||
function handleSummary(raw) {
|
||||
lastUpdate = Date.now(); // reset watchdog
|
||||
@ -260,9 +237,7 @@
|
||||
: [];
|
||||
renderGenericTable('host_metrics', hostData, 'No Stats available');
|
||||
}
|
||||
/* ==========================================================
|
||||
Socket event wiring
|
||||
========================================================== */
|
||||
/* Socket event wiring */
|
||||
socket.on('client_summary', handleSummary);
|
||||
socket.on('connect', () => {
|
||||
safeSetText('client_summary', 'Connected');
|
||||
@ -275,16 +250,12 @@
|
||||
safeSetText('client_summary', `Re-connected (attempt ${attempt})`);
|
||||
requestSummary();
|
||||
});
|
||||
/* ==========================================================
|
||||
Request logic
|
||||
========================================================== */
|
||||
/* Request logic */
|
||||
function requestSummary() {
|
||||
if (!socket.connected) return; // guard against stale emits
|
||||
socket.emit('get_client_summary'); // server will reply via client_summary
|
||||
}
|
||||
/* ==========================================================
|
||||
Recursive polling
|
||||
========================================================== */
|
||||
/* Recursive polling */
|
||||
let pollTimer = null;
|
||||
function pollLoop() {
|
||||
if (!socket.connected) return;
|
||||
@ -294,9 +265,7 @@
|
||||
socket.on('connect', () => {
|
||||
if (!pollTimer) pollLoop();
|
||||
});
|
||||
/* ==========================================================
|
||||
Watchdog - force reconnect if no data for 15 s
|
||||
========================================================== */
|
||||
/* Watchdog - force reconnect if no data for 15 s */
|
||||
function watchdog() {
|
||||
if (Date.now() - lastUpdate > 15000 && socket.connected) {
|
||||
safeSetText('client_summary', 'No updates - reconnecting...');
|
||||
@ -305,9 +274,7 @@
|
||||
setTimeout(watchdog, 5000);
|
||||
}
|
||||
watchdog();
|
||||
/* ==========================================================
|
||||
Keep the 'active' link in sync when the URL changes
|
||||
========================================================== */
|
||||
/* Keep the 'active' link in sync when the URL changes */
|
||||
window.addEventListener('popstate', () => {
|
||||
const selected = getSelectedId().toLowerCase();
|
||||
document.querySelectorAll('#endpointList a').forEach(a =>
|
||||
|
||||
Reference in New Issue
Block a user