v0.116.0: observability pass — always-on debug ring + leveled sweep + agent tab + self-log pull — MinAgent: 0.81.0
Capture layer: LogBuffer always exists; logger = MultiWriter(LevelFilterWriter (stdout, logging.level), ring) so DEBUG detail exists remotely without a config flip while docker logs keep respecting the level. New internal/logx leveled helpers. Report ACK gains controller_log_requested (additive); next report ships controller_log_tail (128KB, consume-once, app-tail wire byte-compatible). Debug page: Vezérlő|Ügynök tabs; agent tab proxies agent /debug/logs with the pre-0.83 notice on typed 404. Sweep: netstorage_job phases, netprobe, handler validation refusals + orphan WARN, SupportsWithSource gate line, agentapi per-call DEBUG, migrate phase lines, tier2/offbox unswallowed persists. Red-proofs: filter-disabled, drain-removed, dropped-phase-line all FAIL. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -212,6 +212,10 @@
|
||||
<span class="section-toggle">▶</span>
|
||||
</div>
|
||||
<div class="card-body debug-section-body" style="display:none">
|
||||
<div class="debug-log-filters" style="margin-bottom:.5rem">
|
||||
<button class="btn btn-xs debug-log-source active" id="log-tab-controller" onclick="setLogSource('controller',this)">Vezérlő</button>
|
||||
<button class="btn btn-xs debug-log-source" id="log-tab-agent" onclick="setLogSource('agent',this)">Ügynök</button>
|
||||
</div>
|
||||
<div class="debug-log-controls">
|
||||
<div class="debug-log-filters">
|
||||
<button class="btn btn-xs debug-log-filter active" data-level="DEBUG" onclick="setLogLevel('DEBUG',this)">DEBUG</button>
|
||||
@@ -583,15 +587,24 @@ function triggerDR() {
|
||||
});
|
||||
}
|
||||
|
||||
// ── Section 8: Log viewer ──
|
||||
// ── Section 8: Log viewer (Vezérlő | Ügynök tabs — v0.116.0) ──
|
||||
var currentLogLevel = 'DEBUG';
|
||||
var currentLogSource = 'controller';
|
||||
var lastLogTimestamp = '';
|
||||
var LOG_LEVEL_PRIORITY = {DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3};
|
||||
function setLogLevel(level, btn) {
|
||||
currentLogLevel = level;
|
||||
document.querySelectorAll('.debug-log-filter').forEach(function(b) { b.classList.remove('active'); });
|
||||
btn.classList.add('active');
|
||||
refreshLogs();
|
||||
}
|
||||
function setLogSource(source, btn) {
|
||||
currentLogSource = source;
|
||||
document.querySelectorAll('.debug-log-source').forEach(function(b) { b.classList.remove('active'); });
|
||||
btn.classList.add('active');
|
||||
clearLogDisplay();
|
||||
refreshLogs();
|
||||
}
|
||||
function initLogViewer() {
|
||||
refreshLogs();
|
||||
if (document.getElementById('log-auto-refresh').checked) {
|
||||
@@ -606,6 +619,7 @@ function toggleLogAutoRefresh() {
|
||||
}
|
||||
}
|
||||
function refreshLogs(append) {
|
||||
if (currentLogSource === 'agent') { refreshAgentLogs(); return; }
|
||||
var url = '/api/debug/logs?level=' + currentLogLevel + '&limit=500';
|
||||
if (append && lastLogTimestamp) url += '&after=' + encodeURIComponent(lastLogTimestamp);
|
||||
fetch(url, {headers: csrfHeaders()}).then(function(r){return r.json()}).then(function(data) {
|
||||
@@ -630,6 +644,37 @@ function refreshLogs(append) {
|
||||
document.getElementById('log-count').textContent = viewer.children.length + ' / ' + total + ' bejegyzés';
|
||||
}).catch(function(){});
|
||||
}
|
||||
// The agent tab: full refresh each poll (the agent ring is small), client-side level
|
||||
// filter. A pre-0.83 agent (unsupported) renders the notice instead of an error.
|
||||
function refreshAgentLogs() {
|
||||
fetch('/api/debug/agent-logs', {headers: csrfHeaders()}).then(function(r){return r.json()}).then(function(data) {
|
||||
var viewer = document.getElementById('log-viewer');
|
||||
viewer.innerHTML = '';
|
||||
if (!data.ok) {
|
||||
viewer.innerHTML = '<div class="debug-log-entry debug-log-warn">' + escapeHtml(data.error || 'Hiba') + '</div>';
|
||||
document.getElementById('log-count').textContent = '';
|
||||
return;
|
||||
}
|
||||
if (data.data && data.data.unsupported) {
|
||||
viewer.innerHTML = '<div class="debug-log-entry">' + escapeHtml(data.data.notice) + '</div>';
|
||||
document.getElementById('log-count').textContent = '';
|
||||
return;
|
||||
}
|
||||
var entries = (data.data && data.data.entries) || [];
|
||||
var total = (data.data && data.data.total) || 0;
|
||||
var min = LOG_LEVEL_PRIORITY[currentLogLevel] || 0;
|
||||
entries.forEach(function(e) {
|
||||
if ((LOG_LEVEL_PRIORITY[e.level] || 0) < min) return;
|
||||
var div = document.createElement('div');
|
||||
div.className = 'debug-log-entry debug-log-' + e.level.toLowerCase();
|
||||
var ts = e.timestamp ? fmtTime(e.timestamp) : '';
|
||||
div.innerHTML = '<span class="text-muted">' + ts + '</span> <span class="debug-log-level">[' + e.level + ']</span> ' + escapeHtml(e.message);
|
||||
viewer.appendChild(div);
|
||||
});
|
||||
viewer.scrollTop = viewer.scrollHeight;
|
||||
document.getElementById('log-count').textContent = viewer.children.length + ' / ' + total + ' bejegyzés';
|
||||
}).catch(function(){});
|
||||
}
|
||||
function clearLogDisplay() {
|
||||
document.getElementById('log-viewer').innerHTML = '';
|
||||
document.getElementById('log-count').textContent = '';
|
||||
|
||||
Reference in New Issue
Block a user