feat: traefik UI (per-router dashboard with SVG sparklines)

This commit is contained in:
2026-03-18 18:43:05 -04:00
parent aacfcd420e
commit 2164ea28f2
2 changed files with 123 additions and 0 deletions
@@ -0,0 +1,53 @@
{# plugins/traefik/templates/traefik/index.html #}
{% extends "base.html" %}
{% block title %}Traefik — FabledNetMon{% endblock %}
{% block content %}
<h1 style="color:#c0c0ff;margin-bottom:1.5rem;">Traefik Routers</h1>
{% if not router_data %}
<div class="card">
<p style="color:#606080;">No Traefik metrics yet. Configure <code>metrics_url</code> in <code>config.yaml</code> under <code>plugins.traefik</code>.</p>
</div>
{% else %}
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:1rem;">
{% for r in router_data %}
<div class="card">
<h3 style="color:#8080ff;margin-bottom:0.75rem;font-size:0.95rem;word-break:break-all;">{{ r.name }}</h3>
<table style="width:100%;border-collapse:collapse;font-size:0.85rem;">
<tr>
<td style="color:#606080;padding:0.2rem 0;">Req/s</td>
<td style="color:#c0c0e0;padding:0.2rem 0.5rem;">{{ "%.2f"|format(r.latest.request_rate) }}</td>
<td style="padding:0.2rem 0;">{{ r.sparkline_req | safe }}</td>
</tr>
<tr>
<td style="color:#606080;padding:0.2rem 0;">p95 ms</td>
<td style="color:#c0c0e0;padding:0.2rem 0.5rem;">{{ "%.1f"|format(r.latest.latency_p95_ms) }}</td>
<td style="padding:0.2rem 0;">{{ r.sparkline_p95 | safe }}</td>
</tr>
<tr>
<td style="color:#606080;padding:0.2rem 0;">p99 ms</td>
<td style="color:#e0e0e0;padding:0.2rem 0.5rem;">{{ "%.1f"|format(r.latest.latency_p99_ms) }}</td>
<td style="padding:0.2rem 0;"></td>
</tr>
<tr>
<td style="color:#606080;padding:0.2rem 0;">4xx %</td>
<td style="color:{% if r.latest.error_rate_4xx_pct > 1 %}#c0a000{% else %}#40a040{% endif %};padding:0.2rem 0.5rem;">
{{ "%.1f"|format(r.latest.error_rate_4xx_pct) }}%
</td>
<td style="padding:0.2rem 0;"></td>
</tr>
<tr>
<td style="color:#606080;padding:0.2rem 0;">5xx %</td>
<td style="color:{% if r.latest.error_rate_5xx_pct > 0.1 %}#a04040{% else %}#40a040{% endif %};padding:0.2rem 0.5rem;">
{{ "%.1f"|format(r.latest.error_rate_5xx_pct) }}%
</td>
<td style="padding:0.2rem 0;">{{ r.sparkline_5xx | safe }}</td>
</tr>
</table>
<div style="color:#404060;font-size:0.75rem;margin-top:0.5rem;">
Last scraped {{ r.latest.scraped_at.strftime("%H:%M:%S") }} UTC
</div>
</div>
{% endfor %}
</div>
{% endif %}
{% endblock %}