|
|
|
@@ -1193,6 +1193,19 @@ input.input-error { |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div class="sidebar-section"> |
|
|
|
<div class="sidebar-title">Control Audit</div> |
|
|
|
<div class="section-note">Counts of 4xx rejects recorded by the control plane APIs.</div> |
|
|
|
<div class="kv"> |
|
|
|
<div class="k">Rejects total</div><div class="v" id="audit-total">--</div> |
|
|
|
<div class="k">405 Method Not Allowed</div><div class="v" id="audit-methodNotAllowed">--</div> |
|
|
|
<div class="k">415 Unsupported Media Type</div><div class="v" id="audit-unsupportedMediaType">--</div> |
|
|
|
<div class="k">413 Request Too Large</div><div class="v" id="audit-bodyTooLarge">--</div> |
|
|
|
<div class="k">400 Unexpected Body</div><div class="v" id="audit-unexpectedBody">--</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="card panel" data-panel-key="shortcuts"> |
|
|
|
<div class="panel-head" data-panel> |
|
|
|
<h2>Shortcuts</h2> |
|
|
|
@@ -1974,6 +1987,7 @@ function render() { |
|
|
|
updateText('info-live', engine.state ? `${String(engine.state).toUpperCase()} / ${state.server.runtimeOk ? 'runtime ok' : 'runtime pending'}` : (state.server.configOk ? 'config only' : '--')); |
|
|
|
|
|
|
|
updateHealth(engine, driver, audioStream); |
|
|
|
updateControlAudit(runtime.controlAudit); |
|
|
|
updateFaultHistory(engine); |
|
|
|
updateTransitionHistory(); |
|
|
|
updateResetHint(engine); |
|
|
|
@@ -2248,6 +2262,40 @@ function updateHealth(engine, driver, audioStream) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function updateControlAudit(audit) { |
|
|
|
const entries = [ |
|
|
|
{ key: 'methodNotAllowed', id: 'audit-methodNotAllowed' }, |
|
|
|
{ key: 'unsupportedMediaType', id: 'audit-unsupportedMediaType' }, |
|
|
|
{ key: 'bodyTooLarge', id: 'audit-bodyTooLarge' }, |
|
|
|
{ key: 'unexpectedBody', id: 'audit-unexpectedBody' }, |
|
|
|
]; |
|
|
|
let total = 0; |
|
|
|
let hasData = false; |
|
|
|
entries.forEach(({ key, id }) => { |
|
|
|
const raw = audit && typeof audit[key] !== 'undefined' ? Number(audit[key]) : NaN; |
|
|
|
const value = Number.isFinite(raw) ? raw : null; |
|
|
|
if (value != null) { |
|
|
|
hasData = true; |
|
|
|
total += value; |
|
|
|
} |
|
|
|
setAuditValue(id, value); |
|
|
|
}); |
|
|
|
setAuditValue('audit-total', hasData ? total : null); |
|
|
|
} |
|
|
|
|
|
|
|
function setAuditValue(id, count) { |
|
|
|
const el = $(id); |
|
|
|
if (!el) return; |
|
|
|
if (count == null) { |
|
|
|
el.textContent = '--'; |
|
|
|
el.className = 'val'; |
|
|
|
return; |
|
|
|
} |
|
|
|
el.textContent = String(count); |
|
|
|
el.className = 'val ' + (count > 0 ? 'warn' : 'good'); |
|
|
|
} |
|
|
|
|
|
|
|
function updateFaultHistory(engine) { |
|
|
|
const container = $('fault-history'); |
|
|
|
if (!container) return; |
|
|
|
|