73 lines
3.0 KiB
Plaintext
73 lines
3.0 KiB
Plaintext
@page
|
|
@model LogsModel
|
|
@{
|
|
ViewData["Title"] = "Log Stream";
|
|
ViewData["Page"] = "logs";
|
|
}
|
|
|
|
<div class="section-header">
|
|
<span class="section-title">Log Stream</span>
|
|
<span class="mono" style="font-size:11px;color:var(--text-muted)">@Model.TotalCount entries</span>
|
|
</div>
|
|
|
|
<form method="get" class="filter-bar">
|
|
<select name="Level" class="form-control" onchange="this.form.submit()">
|
|
<option value="">All Levels</option>
|
|
@foreach (var lvl in new[] { "debug", "info", "warning", "error", "critical" })
|
|
{
|
|
<option value="@lvl" selected="@(Model.Level?.ToLower() == lvl)">@lvl.ToUpper()</option>
|
|
}
|
|
</select>
|
|
<select name="Source" class="form-control" onchange="this.form.submit()">
|
|
<option value="">All Sources</option>
|
|
@foreach (var s in Model.Sources)
|
|
{
|
|
<option value="@s" selected="@(Model.Source == s)">@s</option>
|
|
}
|
|
</select>
|
|
<input id="log-search" type="text" name="Search" value="@Model.Search" placeholder="Search messages..." class="form-control" style="max-width:300px" />
|
|
<a href="/logs" class="btn btn-outline btn-sm">Clear</a>
|
|
</form>
|
|
|
|
<div class="log-stream" id="log-stream">
|
|
@if (!Model.Entries.Any())
|
|
{
|
|
<div class="empty-state">
|
|
<div class="empty-state-icon">▦</div>
|
|
<div class="empty-state-text">No log entries match your filters</div>
|
|
</div>
|
|
}
|
|
@foreach (var e in Model.Entries.AsEnumerable().Reverse())
|
|
{
|
|
<div class="log-entry">
|
|
<span class="log-ts">@e.Timestamp.ToString("yyyy-MM-dd HH:mm:ss")</span>
|
|
<span class="log-level @e.Level.ToLower()">@e.Level.ToUpper()</span>
|
|
<span class="log-source">@e.Source</span>
|
|
<span class="log-message">
|
|
@e.Message
|
|
@if (!string.IsNullOrEmpty(e.Exception))
|
|
{
|
|
<details style="margin-top:3px">
|
|
<summary style="color:var(--down);cursor:pointer;font-size:10px">Exception ▾</summary>
|
|
<pre style="font-size:10px;color:var(--text-muted);margin-top:4px;white-space:pre-wrap">@e.Exception</pre>
|
|
</details>
|
|
}
|
|
</span>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
@if (Model.TotalPages > 1)
|
|
{
|
|
<div class="flex gap-2 mt-2 align-center">
|
|
@if (Model.PageIndex > 1)
|
|
{
|
|
<a href="@Url.Page("/Logs", null, new { PageIndex = Model.PageIndex - 1, Level = Model.Level, Source = Model.Source, Search = Model.Search }, null)" class="btn btn-outline btn-sm">← Prev</a>
|
|
}
|
|
<span class="mono" style="font-size:11px;color:var(--text-muted)">Page @Model.PageIndex of @Model.TotalPages</span>
|
|
@if (Model.PageIndex < Model.TotalPages)
|
|
{
|
|
<a href="@Url.Page("/Logs", null, new { PageIndex = Model.PageIndex + 1, Level = Model.Level, Source = Model.Source, Search = Model.Search }, null)" class="btn btn-outline btn-sm">Next →</a>
|
|
}
|
|
</div>
|
|
} |