Refactoing Worker Dashboard
This commit is contained in:
parent
425821bce7
commit
0edd5841d6
|
|
@ -502,27 +502,35 @@ function renderWorkersTable(msg) {
|
||||||
html += '<tr>';
|
html += '<tr>';
|
||||||
html += '<th>Hostname</th>';
|
html += '<th>Hostname</th>';
|
||||||
html += '<th>Status</th>';
|
html += '<th>Status</th>';
|
||||||
html += '<th>Hardware</th>';
|
|
||||||
html += '<th><i class="fa fa-microchip"></i> CPU</th>';
|
html += '<th><i class="fa fa-microchip"></i> CPU</th>';
|
||||||
html += '<th><i class="fa fa-memory"></i> RAM</th>';
|
html += '<th><i class="fa fa-memory"></i> RAM</th>';
|
||||||
html += '<th><i class="fa fa-dice-d20"></i> GPU</th>';
|
html += '<th><i class="fa fa-dice-d20"></i> GPU</th>';
|
||||||
html += '<th>Uptime</th>';
|
|
||||||
html += '<th>Last Seen</th>';
|
|
||||||
html += '</tr>';
|
html += '</tr>';
|
||||||
html += '</thead>';
|
html += '</thead>';
|
||||||
html += '<tbody>';
|
html += '<tbody>';
|
||||||
|
|
||||||
|
const nowSec = Math.floor(Date.now() / 1000);
|
||||||
|
const staleThresholdSec = 60;
|
||||||
|
|
||||||
for (const [sdl_id, worker] of Object.entries(workers)) {
|
for (const [sdl_id, worker] of Object.entries(workers)) {
|
||||||
const status = worker.status === 'active'
|
const ageSec = nowSec - worker.last_seen_utime;
|
||||||
|
const isActive = ageSec <= staleThresholdSec;
|
||||||
|
|
||||||
|
// Status badge
|
||||||
|
const statusBadge = isActive
|
||||||
? '<span class="badge bg-success">Active</span>'
|
? '<span class="badge bg-success">Active</span>'
|
||||||
: '<span class="badge bg-secondary">Inactive</span>';
|
: '<span class="badge bg-danger">Inactive</span>'; // ✅ Red instead of grey
|
||||||
|
|
||||||
// Hardware info
|
// Hardware info
|
||||||
const hwType = worker.hardware?.type || 'unknown';
|
const hwType = worker.hardware?.type || 'unknown';
|
||||||
const hwIcon = hwType === 'hw' ? '🖥️' : hwType === 'vm' ? '💠' : '❓';
|
const hwIcon = hwType === 'hw' ? '🖥️' : hwType === 'vm' ? '💠' : '❓';
|
||||||
const hwManuf = worker.hardware?.manufacturer || 'Unknown';
|
const hwManuf = worker.hardware?.manufacturer || 'Unknown';
|
||||||
const hwModel = worker.hardware?.model || 'Unknown';
|
const hwModel = worker.hardware?.model || 'Unknown';
|
||||||
const hardware = `<span title="${hwManuf} - ${hwModel}">${hwIcon} ${hwType === 'vm' ? hwModel : hwManuf}</span>`;
|
|
||||||
|
// ✅ Full hardware display with model
|
||||||
|
const hardwareDisplay = hwType === 'vm'
|
||||||
|
? `${hwIcon} ${hwModel}`
|
||||||
|
: `${hwIcon} ${hwManuf} ${hwModel}`;
|
||||||
|
|
||||||
// CPU
|
// CPU
|
||||||
const cpuAvail = worker.resources?.cpus?.available || 0;
|
const cpuAvail = worker.resources?.cpus?.available || 0;
|
||||||
|
|
@ -536,7 +544,6 @@ function renderWorkersTable(msg) {
|
||||||
|
|
||||||
const memAvailGB = Math.round(memAvail / (1024 * 1024 * 1024));
|
const memAvailGB = Math.round(memAvail / (1024 * 1024 * 1024));
|
||||||
const memTotalGB = Math.round(memTotal / (1024 * 1024 * 1024));
|
const memTotalGB = Math.round(memTotal / (1024 * 1024 * 1024));
|
||||||
const memUsedGB = Math.round(memUsed / (1024 * 1024 * 1024));
|
|
||||||
const memPercent = worker.usage?.memory?.percent_used || 0;
|
const memPercent = worker.usage?.memory?.percent_used || 0;
|
||||||
|
|
||||||
// GPU
|
// GPU
|
||||||
|
|
@ -548,32 +555,57 @@ function renderWorkersTable(msg) {
|
||||||
const gpuMemGB = Math.round(gpuMemMB / 1024);
|
const gpuMemGB = Math.round(gpuMemMB / 1024);
|
||||||
|
|
||||||
// Uptime
|
// Uptime
|
||||||
const uptime = worker.uptime?.proc_dhms || 'N/A';
|
const procUptime = worker.uptime?.proc_dhms || 'N/A';
|
||||||
|
const sysUptime = worker.uptime?.sys_dhms || 'N/A';
|
||||||
|
|
||||||
// Last seen
|
// ✅ Last seen age
|
||||||
const lastSeen = worker.last_seen
|
const days = Math.floor(ageSec / 86400);
|
||||||
? new Date(worker.last_seen).toLocaleString()
|
const hours = Math.floor((ageSec % 86400) / 3600);
|
||||||
: 'N/A';
|
const minutes = Math.floor((ageSec % 3600) / 60);
|
||||||
|
const seconds = Math.floor(ageSec % 60);
|
||||||
|
|
||||||
|
let lastSeenAge = '';
|
||||||
|
if (days > 0) lastSeenAge += `${days}d `;
|
||||||
|
if (hours > 0 || days > 0) lastSeenAge += `${hours}h `;
|
||||||
|
if (minutes > 0 || hours > 0 || days > 0) lastSeenAge += `${minutes}m `;
|
||||||
|
lastSeenAge += `${seconds}s ago`;
|
||||||
|
|
||||||
html += '<tr>';
|
html += '<tr>';
|
||||||
html += `<td><strong>${worker.hostname}</strong><br><small class="text-muted" style="font-size:0.7em">${worker.sdl_id.substring(0, 8)}...</small></td>`;
|
|
||||||
html += `<td>${status}</td>`;
|
// ✅ Hostname column with hardware underneath
|
||||||
html += `<td><small>${hardware}</small></td>`;
|
html += `<td>
|
||||||
|
<strong>${worker.hostname}</strong><br>
|
||||||
|
<small class="text-muted" style="font-size:0.7em">${worker.sdl_id}</small><br>
|
||||||
|
<small class="text-muted" style="font-size:0.8em">${hardwareDisplay}</small>
|
||||||
|
</td>`;
|
||||||
|
|
||||||
|
// ✅ Status column with uptime and last seen
|
||||||
|
html += `<td>
|
||||||
|
${statusBadge}<br>
|
||||||
|
<small class="text-muted">SDL: ${procUptime}</small><br>
|
||||||
|
<small class="text-muted">OS: ${sysUptime}</small><br>
|
||||||
|
<small class="text-muted">${lastSeenAge}</small>
|
||||||
|
</td>`;
|
||||||
|
|
||||||
|
// CPU
|
||||||
html += `<td>
|
html += `<td>
|
||||||
<span class="dash-val">${cpuAvail}</span> / ${cpuTotal}
|
<span class="dash-val">${cpuAvail}</span> / ${cpuTotal}
|
||||||
${cpuUsed > 0 ? `<br><small class="text-muted">${cpuUsed}% load</small>` : ''}
|
${cpuUsed > 0 ? `<br><small class="text-muted">${cpuUsed}% load</small>` : ''}
|
||||||
</td>`;
|
</td>`;
|
||||||
|
|
||||||
|
// Memory
|
||||||
html += `<td>
|
html += `<td>
|
||||||
<span class="dash-val">${memAvailGB}</span> / ${memTotalGB} GB
|
<span class="dash-val">${memAvailGB}</span> / ${memTotalGB} GB
|
||||||
${memPercent > 0 ? `<br><small class="text-muted">${memPercent}% used</small>` : ''}
|
${memPercent > 0 ? `<br><small class="text-muted">${memPercent}% used</small>` : ''}
|
||||||
</td>`;
|
</td>`;
|
||||||
|
|
||||||
|
// GPU
|
||||||
html += `<td>
|
html += `<td>
|
||||||
<span class="dash-val">${gpuAvail}</span> / ${gpuTotal}
|
<span class="dash-val">${gpuAvail}</span> / ${gpuTotal}
|
||||||
${gpuMemGB > 0 ? `<br><small class="text-muted">(${gpuMemGB} GB)</small>` : ''}
|
${gpuMemGB > 0 ? `<br><small class="text-muted">(${gpuMemGB} GB)</small>` : ''}
|
||||||
${gpuUsed > 0 ? `<br><small class="text-muted">${gpuUsed}% load</small>` : ''}
|
${gpuUsed > 0 ? `<br><small class="text-muted">${gpuUsed}% load</small>` : ''}
|
||||||
</td>`;
|
</td>`;
|
||||||
html += `<td><small>${uptime}</small></td>`;
|
|
||||||
html += `<td><small>${lastSeen}</small></td>`;
|
|
||||||
html += '</tr>';
|
html += '</tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -525,11 +525,12 @@ function getSystemHardware() {
|
||||||
try {
|
try {
|
||||||
const piModel = fs.readFileSync('/proc/device-tree/model', 'utf8')
|
const piModel = fs.readFileSync('/proc/device-tree/model', 'utf8')
|
||||||
.replace(/\0/g, '')
|
.replace(/\0/g, '')
|
||||||
|
.replace(/Raspberry Pi/, '')
|
||||||
.trim();
|
.trim();
|
||||||
|
|
||||||
if (piModel) {
|
if (piModel) {
|
||||||
hardware.type = 'hw'; // ✅ Changed from 'physical'
|
hardware.type = 'hw'; // ✅ Changed from 'physical'
|
||||||
hardware.manufacturer = 'Raspberry Pi Foundation';
|
hardware.manufacturer = 'Raspberry Pi';
|
||||||
hardware.model = piModel;
|
hardware.model = piModel;
|
||||||
return hardware;
|
return hardware;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue