Remotely/Server/Components/Pages/ServerLogs.razor
2024-02-19 15:28:07 -08:00

178 lines
4.5 KiB
Plaintext

@page "/server-logs"
@using System.Collections.ObjectModel;
@attribute [Authorize(Policy = PolicyNames.ServerAdminRequired)]
@inherits AuthComponentBase
@inject IDataService DataService
@inject IToastService ToastService
@inject IJsInterop JsInterop
@inject ILogsManager LogsManager
@inject ILoaderService LoaderService
<h3 class="mb-3">Server Logs</h3>
<div class="buttons-row mb-3">
<div>
<button class="btn btn-danger" type="button" @onclick="ClearAllLogs">
Delete Logs
</button>
</div>
<div>
<button class="btn btn-primary"
onclick="window.open('/API/ServerLogs/Download', '_blank')">
Download Logs
</button>
</div>
<div>
<button class="btn btn-primary"
onclick="window.open('/API/ScriptResults', '_blank')">
Download Script History
</button>
</div>
</div>
<div class="filters-row mb-3">
<div style="display:inline-block">
<strong>Type:</strong>
<br />
<select class="form-control-sm" @bind="LogLevel">
<option value="">All</option>
@foreach (var eventType in Enum.GetValues(typeof(LogLevel)))
{
<option @key="eventType" value="@eventType">@eventType</option>
}
</select>
</div>
<div style="display:inline-block">
<strong>Filter:</strong>
<br />
<input type="text" @bind="MessageFilter" @bind:event="oninput" />
</div>
<div style="display:inline-block">
<strong>From:</strong>
<br />
<input type="date" @bind="FromDate" />
</div>
<div style="display:inline-block">
<strong>To:</strong>
<br />
<input type="date" @bind="ToDate" />
</div>
</div>
<textarea readonly class="logs-content bg-dark text-white">
@(string.Join(Environment.NewLine, _filteredLogs))
</textarea>
@code {
private readonly string _messageDebounceKey = Guid.NewGuid().ToString();
private readonly List<string> _filteredLogs = new();
private LogLevel? _logLevel;
private string _messageFilter = string.Empty;
private DateTimeOffset _fromDate = DateTimeOffset.Now.AddDays(-1);
private DateTimeOffset _toDate = DateTimeOffset.Now;
private DateTimeOffset FromDate
{
get => _fromDate;
set
{
if (value > _toDate)
{
ToastService.ShowToast("Invalid date range.", classString: "bg-warning");
return;
}
_fromDate = value;
_ = RefreshLogs();
}
}
private LogLevel? LogLevel
{
get => _logLevel;
set
{
_logLevel = value;
_ = RefreshLogs();
}
}
private string MessageFilter
{
get => _messageFilter;
set
{
_messageFilter = value;
Debouncer.Debounce(
TimeSpan.FromSeconds(1),
() => _ = RefreshLogs(),
_messageDebounceKey);
}
}
private DateTimeOffset ToDate
{
get => _toDate;
set
{
if (value < _fromDate)
{
ToastService.ShowToast("Invalid date range.", classString: "bg-warning");
return;
}
_toDate = value;
_ = RefreshLogs();
}
}
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (firstRender)
{
await RefreshLogs();
}
}
private async Task ClearAllLogs()
{
var result = await JsInterop.Confirm("Are you sure you want to delete all previous logs? Today's logs are retained.");
if (result)
{
using (var _ = LoaderService.ShowLoader("Deleting logs"))
{
await LogsManager.DeleteLogs();
}
await RefreshLogs();
ToastService.ShowToast("Logs deleted.");
}
}
private async Task RefreshLogs()
{
using var _ = await LoaderService.ShowLoader("Refreshing logs");
_filteredLogs.Clear();
var logsAsync = LogsManager.GetLogs(
_fromDate,
_toDate,
_messageFilter,
_logLevel);
await foreach (var line in logsAsync)
{
_filteredLogs.Add(line);
}
await InvokeAsync(StateHasChanged);
}
}