feat(syslog): lines beside the readings: around an anomaly, in get_anomaly, and marked on host and SNMP charts (#6002)
CI / lint (push) Successful in 2s
CI / unit (push) Successful in 1m29s
CI / integration (push) Successful in 1m37s
CI / publish (push) Successful in 1m9s

get_anomaly's circumstances gain the host's or SNMP device's syslog
warnings and worse (mcp_events / mcp_resource_events). An anomaly row opens
"Syslog around it", read only when opened. A shared Chart.js plugin
(chart-marks.js) draws a dashed line at each syslog error on the host
metrics charts and an SNMP device's charts, with a line saying how many.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 06:36:31 -04:00
co-authored by Claude Opus 5.5
parent f37a578136
commit 521d84f318
12 changed files with 335 additions and 23 deletions
@@ -0,0 +1,25 @@
{# plugins/syslog/templates/syslog/_around.html — an anomaly's syslog: the
warnings and worse nearest its start, from the sources shown with its
resource (#6002). Loaded when its "Syslog around it" is opened. #}
{% from "syslog/_tone.html" import tone %}
{% if not sources %}
<p class="field-hint" style="margin:0.3rem 0 0;">No added syslog source is shown with this resource.</p>
{% elif not lines %}
<p class="field-hint" style="margin:0.3rem 0 0;">No warnings or worse from {% for s in sources %}{% if not loop.first %}, {% endif %}<a href="/plugins/syslog/sources/{{ s.id }}">{{ s.name }}</a>{% endfor %} from half an hour before to half an hour after.</p>
{% else %}
<table class="table" style="font-size:0.78rem;margin-top:0.3rem;">
<thead><tr><th class="nowrap">Received ({{ tz_label() }})</th>{% if sources|length > 1 %}<th>Source</th>{% endif %}<th>Severity</th><th>App</th><th>Message</th></tr></thead>
<tbody>
{% for ln in lines %}
<tr>
<td class="nowrap">{{ ln.received_at|when(seconds=true) }}</td>
{% if sources|length > 1 %}<td class="nowrap"><a href="/plugins/syslog/sources/{{ ln.source_id }}">{{ ln.source }}</a></td>{% endif %}
<td class="nowrap"><span class="{{ tone(ln.level) }}">{{ ln.severity }}</span></td>
<td class="nowrap">{{ ln.app or "—" }}</td>
<td class="mono" style="max-width:32rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="{{ ln.message }}">{{ ln.message }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if more > 0 %}<p class="field-hint" style="margin:0.3rem 0 0;">{{ more }} more in that hour either side, further from its start: open the source to read them.</p>{% endif %}
{% endif %}