Skip to main content

max / makenotwork

3.1 KB · 92 lines History Blame Raw
1 {% extends "base.html" %}
2
3 {% block title %}Admin: Metrics - Makenot.work{% endblock %}
4 {% block body_attrs %} class="padded-page admin-page"{% endblock %}
5
6 {% block head %}
7 {% endblock %}
8
9 {% block content %}
10 {% include "partials/site_header.html" %}
11
12 <div class="container">
13 {% include "partials/admin_nav.html" %}
14
15 <h1 class="page-title">Metrics</h1>
16 <p class="refresh-note">
17 Uptime: {{ uptime }}.
18 <button class="btn-secondary btn-tiny"
19 hx-get="/admin/metrics" hx-target="body" hx-swap="outerHTML">Refresh</button>
20 </p>
21
22 <div class="metrics-grid">
23 <div class="metric-card">
24 <div class="value">{{ total_requests }}</div>
25 <div class="label">Total requests</div>
26 </div>
27 <div class="metric-card{% if error_rate > 5.0 %} error{% elif error_rate > 1.0 %} warn{% endif %}">
28 <div class="value">{{ error_rate|fmt("{:.1}") }}%</div>
29 <div class="label">Error rate (5xx)</div>
30 </div>
31 <div class="metric-card">
32 <div class="value">{{ total_errors }}</div>
33 <div class="label">App errors</div>
34 </div>
35 <div class="metric-card{% if pool_active as f64 / pool_max as f64 > 0.8 %} warn{% endif %}">
36 <div class="value">{{ pool_active }} / {{ pool_max }}</div>
37 <div class="label">DB pool (active / max)</div>
38 </div>
39 <div class="metric-card">
40 <div class="value">{{ pool_idle }}</div>
41 <div class="label">DB pool idle</div>
42 </div>
43 </div>
44
45 {% if !top_routes.is_empty() %}
46 <h2 class="section-heading">Top Routes (by request count)</h2>
47 <table>
48 <thead>
49 <tr>
50 <th>Method</th>
51 <th>Path</th>
52 <th>Status</th>
53 <th>Count</th>
54 </tr>
55 </thead>
56 <tbody>
57 {% for r in top_routes %}
58 <tr>
59 <td class="mono">{{ r.method }}</td>
60 <td class="mono">{{ r.path }}</td>
61 <td class="mono">{{ r.status }}</td>
62 <td class="mono">{{ r.count }}</td>
63 </tr>
64 {% endfor %}
65 </tbody>
66 </table>
67 {% endif %}
68
69 {% if !error_breakdown.is_empty() %}
70 <h2 class="section-heading">Errors by Kind</h2>
71 <table>
72 <thead>
73 <tr>
74 <th>Kind</th>
75 <th>Count</th>
76 </tr>
77 </thead>
78 <tbody>
79 {% for e in error_breakdown %}
80 <tr>
81 <td class="mono">{{ e.kind }}</td>
82 <td class="mono">{{ e.count }}</td>
83 </tr>
84 {% endfor %}
85 </tbody>
86 </table>
87 {% endif %}
88
89 <p class="grafana-link">Full dashboards: <a href="http://100.120.174.96:3100" target="_blank">Grafana</a> (Tailscale only)</p>
90 </div>
91 {% endblock %}
92