Add live log viewer and enable file logging in service

This commit is contained in:
Gemini Bot
2026-01-20 13:19:06 +00:00
parent 6e2a9d5b2e
commit 507c4a10ea
4 changed files with 92 additions and 15 deletions

View File

@@ -52,27 +52,58 @@ document.addEventListener('DOMContentLoaded', function() {
// Update Top Stats
if (summary) {
// Cgminer returns MHS in different fields depending on version, usually "MHS 5s" or similar
// The API returns dict keys.
// Let's inspect typical cgminer summary keys: "MHS av", "MHS 5s", "Accepted", "Hardware Errors", "Utility"
const mhs = summary['MHS 5s'] || summary['MHS av'] || 0;
document.getElementById('stat-mhs').innerText = parseFloat(mhs).toFixed(2);
document.getElementById('stat-accepted').innerText = formatNumber(summary['Accepted'] || 0);
document.getElementById('stat-hw').innerText = formatNumber(summary['Hardware Errors'] || 0);
}
// Update Device Count
if (devs) {
document.getElementById('stat-devices').innerText = devs.length;
}
// Update Max Temp
// Helper to find temp in stats if missing in devs
// Cgminer 'stats' command returns specific driver info.
// Structure: stats ->STATS -> list of dicts. usually one dict per device with ID keys like 'MM ID 0', etc.
// Or simplified list.
function getTempFallback(devId, statsData) {
// Try to find matching ID in stats
// This is heuristic as structure varies wildy between forks
return 0;
}
// Update Devs Table & Max Temp
let maxTemp = 0;
const tbody = document.getElementById('devs-table-body');
tbody.innerHTML = '';
if (devs && devs.length > 0) {
devs.forEach(dev => {
if (dev['Temperature'] > maxTemp) maxTemp = dev['Temperature'];
let temp = dev['Temperature'] || 0;
// Fallback logic could go here if we understood the STATS structure for this specific fork
// For now we rely on standard API.
if (temp > maxTemp) maxTemp = temp;
const tr = document.createElement('tr');
tr.innerHTML = `
<td>${dev['ID']}</td>
<td>${dev['Name'] || 'Gridseed'}</td>
<td>${dev['Enabled']}</td>
<td>${dev['Status']}</td>
<td class="${temp > 50 ? 'text-warning' : 'text-success'}">${temp > 0 ? temp.toFixed(1) : '-'}</td>
<td>${parseFloat(dev['MHS 5s'] || 0).toFixed(2)}</td>
<td>${parseFloat(dev['MHS av'] || 0).toFixed(2)}</td>
<td>${dev['Accepted']}</td>
<td>${dev['Rejected']}</td>
<td>${dev['Hardware Errors']}</td>
`;
tbody.appendChild(tr);
});
} else {
tbody.innerHTML = '<tr><td colspan="10" class="text-center text-muted">Keine Geräte gefunden...</td></tr>';
}
document.getElementById('stat-temp').innerText = maxTemp.toFixed(1);
@@ -140,7 +171,26 @@ document.addEventListener('DOMContentLoaded', function() {
.catch(err => console.error('Error fetching data:', err));
}
// Update Log
function updateLog() {
fetch('/api/log')
.then(response => response.json())
.then(data => {
const logDiv = document.getElementById('miner-log');
if (data.log) {
const isScrolledToBottom = logDiv.scrollHeight - logDiv.clientHeight <= logDiv.scrollTop + 1;
logDiv.innerText = data.log;
if (isScrolledToBottom) {
logDiv.scrollTop = logDiv.scrollHeight;
}
}
})
.catch(err => console.error('Error fetching log:', err));
}
// Update every 3 seconds
setInterval(updateDashboard, 3000);
setInterval(updateLog, 5000);
updateDashboard(); // Initial call
updateLog();
});