@page "/logs" @using Microsoft.AspNetCore.Components.WebAssembly.Authentication @using RobotNet.MapShares.Models @inject IJSRuntime JSRuntime @inject IHttpClientFactory HttpClientFactory @inject IConfiguration Configuration @inject ISnackbar Snackbar Logs
@foreach (var proccess in LogsProccess) { @proccess.Name }
@if (ShowRawLog) {
Normal
@foreach (var log in ShowLogs) { @log
}
} else { @if (SearchLogs.Count < ShowLogs.Count) {
Raw log
} @foreach (var log in SearchLogs) {
@log.Time @log.Level @log.Message @if (log.HasException) {
                                    @log.Exception
                                                                    
}
} }
@code { private DateTime DateLog = DateTime.Today; private bool IsLoading; private readonly List ShowLogs = new(); private readonly List SearchLogs = new(); private ElementReference LogContainerRef { get; set; } private bool ShowRawLog { get; set; } private string? FilterLog { get; set; } private List LogsProccess = []; private LogConfiguration LogProccessSelected = new(); protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (!firstRender) return; LogsProccess = Configuration.GetSection("Logs").Get>() ?? []; LogProccessSelected = LogsProccess.FirstOrDefault() ?? new LogConfiguration(); await LoadLogs(); } private async Task LoadLogs() { try { IsLoading = true; ShowLogs.Clear(); StateHasChanged(); using var Http = new HttpClient(); var logs = await Http.GetFromJsonAsync>($"{LogProccessSelected.Url}?date={DateLog}"); ShowLogs.AddRange(logs ?? []); IsLoading = false; StateHasChanged(); await ReloadLogs(); } catch (AccessTokenNotAvailableException ex) { ex.Redirect(); return; } } private async Task ReloadLogs() { IsLoading = true; SearchLogs.Clear(); StateHasChanged(); foreach (var line in ShowLogs.Where(log => string.IsNullOrEmpty(FilterLog) || log.Contains(FilterLog)).TakeLast(2000)) { try { var log = System.Text.Json.JsonSerializer.Deserialize(line); if (log is not null) SearchLogs.Add(log); } catch (System.Text.Json.JsonException) { continue; } } IsLoading = false; StateHasChanged(); await JSRuntime.InvokeVoidAsync("ScrollToBottom", LogContainerRef); } private async Task OnSearch(string text) { FilterLog = text; await ReloadLogs(); } private async Task OnDateChanged(DateTime? date) { if (date is not null && date.HasValue) { DateLog = date.Value; await LoadLogs(); } } public class LogConfiguration { public string Name { get; set; } = ""; public string Url { get; set; } = ""; } private async Task ExportLogs() { try { using var Http = new HttpClient(); var fileContent = await Http.GetFromJsonAsync>($"{LogProccessSelected.Url}?date={DateLog}"); var formattedContent = string.Join("\n", fileContent ?? []); var fileName = $"{LogProccessSelected.Name}_{DateLog.ToShortDateString()}.txt"; await JSRuntime.InvokeVoidAsync("downloadFile", fileName, formattedContent, "text/plain"); } catch (Exception ex) { Snackbar.Add($"Lỗi khi tải file: {ex.Message}", Severity.Warning); } } }