Initial version
This commit is contained in:
80
EonaCat.LogStack.Status/Pages/Analytics.cshtml
Normal file
80
EonaCat.LogStack.Status/Pages/Analytics.cshtml
Normal file
@@ -0,0 +1,80 @@
|
||||
@page
|
||||
@model EonaCat.LogStack.Status.Pages.AnalyticsModel
|
||||
@{
|
||||
ViewData["Title"] = "Analytics";
|
||||
ViewData["Page"] = "analytics";
|
||||
}
|
||||
|
||||
<div class="section-header">
|
||||
<span class="section-title">Uptime & Performance</span>
|
||||
<span class="mono" style="font-size:11px;color:var(--text-muted)">@Model.Reports.Count monitors</span>
|
||||
</div>
|
||||
|
||||
@if (!Model.Reports.Any())
|
||||
{
|
||||
<div class="empty-state">
|
||||
<div class="empty-state-icon">◎</div>
|
||||
<div class="empty-state-text">No check history yet</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="card">
|
||||
<table class="data-table">
|
||||
<thead><tr>
|
||||
<th>Monitor</th>
|
||||
<th>24h Uptime</th>
|
||||
<th>7d Uptime</th>
|
||||
<th>30d Uptime</th>
|
||||
<th>Avg Response</th>
|
||||
<th>Checks (30d)</th>
|
||||
<th>Response Trend</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
@foreach (var r in Model.Reports)
|
||||
{
|
||||
string UptimeCls(double pct) => pct >= 99 ? "rt-good" : pct >= 95 ? "rt-ok" : "rt-slow";
|
||||
<tr>
|
||||
<td style="font-weight:500;color:var(--text-primary)">@r.MonitorName</td>
|
||||
<td class="mono @UptimeCls(r.Uptime24h)" style="font-size:12px">@r.Uptime24h.ToString("F1")%</td>
|
||||
<td class="mono @UptimeCls(r.Uptime7d)" style="font-size:12px">@r.Uptime7d.ToString("F1")%</td>
|
||||
<td class="mono @UptimeCls(r.Uptime30d)" style="font-size:12px">@r.Uptime30d.ToString("F1")%</td>
|
||||
<td class="mono" style="font-size:12px">@((int)r.AvgResponseMs)ms</td>
|
||||
<td class="mono" style="font-size:12px">
|
||||
<span style="color:var(--up)">@r.UpChecks ↑</span>
|
||||
<span style="color:var(--down);margin-left:6px">@r.DownChecks ↓</span>
|
||||
</td>
|
||||
<td>
|
||||
<canvas id="spark-@r.MonitorId" width="90" height="28"
|
||||
data-values="@Model.SparklineData[r.MonitorId]"
|
||||
class="sparkline-canvas"></canvas>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Log error rate chart -->
|
||||
<div class="chart-wrap mt-2">
|
||||
<div style="font-family:var(--font-mono);font-size:10px;color:var(--text-muted);letter-spacing:1px;margin-bottom:10px">LOG ERROR RATE - LAST 24H</div>
|
||||
<canvas id="log-stats-chart" style="height:180px"></canvas>
|
||||
</div>
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js" crossorigin="anonymous"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Render response-time sparklines
|
||||
document.querySelectorAll('.sparkline-canvas').forEach(canvas => {
|
||||
const raw = canvas.dataset.values;
|
||||
if (!raw) return;
|
||||
const values = raw.split(',').map(Number).filter(n => !isNaN(n));
|
||||
drawSparkline(canvas, values, 'rgba(0,212,170,0.7)');
|
||||
});
|
||||
|
||||
loadLogStatsChart('log-stats-chart');
|
||||
});
|
||||
</script>
|
||||
}
|
||||
Reference in New Issue
Block a user