294 lines
9.3 KiB
Plaintext
294 lines
9.3 KiB
Plaintext
@page "/user/logs"
|
|
@page "/user/logs/{DatabaseStr}"
|
|
@page "/user/logs/{DatabaseStr}/{DatabaseInstanceStr}"
|
|
@using Rms.Risk.Mango.Pivot.Core.MongoDb
|
|
@attribute [Authorize]
|
|
|
|
@inject NavigationManager NavigationManager
|
|
@inject IUserSession UserSession
|
|
@inject IJSRuntime JsRuntime
|
|
|
|
@*
|
|
* dbMango
|
|
*
|
|
* Copyright 2025 Deutsche Bank AG
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*@
|
|
|
|
<style>
|
|
.chart-display {
|
|
width: 90vw;
|
|
height: 90vh;
|
|
}
|
|
</style>
|
|
|
|
<h3 class="mt-3">Logs</h3>
|
|
|
|
<AuthorizedOnly Policy="ReadAccess" Resource="@UserSession.Database">
|
|
|
|
<div class="form-row">
|
|
<FormItemSelect Class="mr-2" Name="Category" @bind-Value="_state.LogCategory" Values="@LogCategories" Enabled="@IsReady" />
|
|
<FormItemText Class="mr-2" Name="Rows per page" @bind-Value="RowsPerPageStr" InputType="number" Icon="icon-download-selected-sm" />
|
|
<div class="form-group">
|
|
<FormButton Enabled="@IsReady" Name="Fetch" Icon="icon-search-sm" OnClick="Run" IsPrimary="true" />
|
|
</div>
|
|
</div>
|
|
|
|
@if (Error != null)
|
|
{
|
|
<ExceptionControl Exception="@Error"/>
|
|
}
|
|
|
|
<div class="mr-3 ml-3">
|
|
<TableControl Class="table table-hover table-striped table-forge table-forge-striped mr-3" Items="@Result" PageSize="@_state.RowsPerPage" Filterable="true">
|
|
<TableColumnControl Name="Time" Field="Time">
|
|
<Template>
|
|
<span @onclick="@(() => OnCellClick((LogRecordModel)context.Row))">
|
|
@(((LogRecordModel)context.Row).Time.ToString("yyyy-MM-dd HH:mm:ss.fff"))
|
|
</span>
|
|
</Template>
|
|
</TableColumnControl>
|
|
<TableColumnControl Name="Severity" Field="Severity" Filterable="true" FilterDropdownValues="@AvailableSeverity">
|
|
<Template>
|
|
<span @onclick="@(() => OnCellClick((LogRecordModel)context.Row))">
|
|
@(((LogRecordModel)context.Row).Severity)
|
|
</span>
|
|
</Template>
|
|
</TableColumnControl>
|
|
<TableColumnControl Name="Category" Field="Category" Filterable="true" FilterDropdownValues="@AvailableCategories">
|
|
<Template>
|
|
<span @onclick="@(() => OnCellClick((LogRecordModel)context.Row))">
|
|
@(((LogRecordModel)context.Row).Category)
|
|
</span>
|
|
</Template>
|
|
</TableColumnControl>
|
|
<TableColumnControl Name="Id" Field="Id">
|
|
<Template>
|
|
<span @onclick="@(() => OnCellClick((LogRecordModel)context.Row))">
|
|
@(((LogRecordModel)context.Row).Id)
|
|
</span>
|
|
</Template>
|
|
</TableColumnControl>
|
|
<TableColumnControl Name="Svc" Field="Svc">
|
|
<Template>
|
|
<span @onclick="@(() => OnCellClick((LogRecordModel)context.Row))">
|
|
@(((LogRecordModel)context.Row).Svc)
|
|
</span>
|
|
</Template>
|
|
</TableColumnControl>
|
|
<TableColumnControl Name="Ctx" Field="Ctx">
|
|
<Template>
|
|
<span @onclick="@(() => OnCellClick((LogRecordModel)context.Row))">
|
|
@(((LogRecordModel)context.Row).Ctx)
|
|
</span>
|
|
</Template>
|
|
</TableColumnControl>
|
|
<TableColumnControl Name="Msg" Field="Msg">
|
|
<Template>
|
|
<span @onclick="@(() => OnCellClick((LogRecordModel)context.Row))">
|
|
@(((LogRecordModel)context.Row).Msg)
|
|
</span>
|
|
</Template>
|
|
</TableColumnControl>
|
|
<TableColumnControl Name="Attributes" Field="Attr" Template="@GetAttributes" />
|
|
</TableControl>
|
|
</div>
|
|
|
|
</AuthorizedOnly>
|
|
|
|
@code {
|
|
[CascadingParameter] public IModalService Modal { get; set; } = null!;
|
|
|
|
[Parameter] public string? DatabaseStr { get; set; }
|
|
[Parameter] public string? DatabaseInstanceStr { get; set; }
|
|
|
|
private string Database
|
|
{
|
|
get => UserSession.Database;
|
|
set
|
|
{
|
|
if (UserSession.Database == value)
|
|
return;
|
|
UserSession.Database = value;
|
|
SyncUrl();
|
|
}
|
|
}
|
|
|
|
private string DatabaseInstance
|
|
{
|
|
get => UserSession.DatabaseInstance;
|
|
set
|
|
{
|
|
if (UserSession.DatabaseInstance == value)
|
|
return;
|
|
UserSession.DatabaseInstance = value;
|
|
SyncUrl();
|
|
}
|
|
}
|
|
|
|
|
|
private Exception? Error { get; set; }
|
|
private List<LogRecordModel> Result { get; set; } = new();
|
|
private List<string> AvailableSeverity = [];
|
|
private List<string> AvailableCategories = [];
|
|
|
|
private string RowsPerPageStr
|
|
{
|
|
get => _state.RowsPerPage.ToString();
|
|
set
|
|
{
|
|
if (int.TryParse(value, out var newValue))
|
|
_state.RowsPerPage = newValue;
|
|
}
|
|
}
|
|
|
|
private string[] LogCategories { get; set; } = ["global"];
|
|
private bool IsReady { get; set; } = false;
|
|
|
|
private class LogsPageState
|
|
{
|
|
public string LogCategory { get; set; } = "global";
|
|
public int RowsPerPage { get; set; } = 28;
|
|
}
|
|
|
|
private LogsPageState _state = new();
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
if (!firstRender)
|
|
return;
|
|
|
|
if (string.IsNullOrWhiteSpace(DatabaseStr))
|
|
DatabaseStr = Database;
|
|
else
|
|
Database = DatabaseStr;
|
|
|
|
if (string.IsNullOrWhiteSpace(DatabaseInstanceStr))
|
|
DatabaseInstanceStr = DatabaseInstance;
|
|
else
|
|
DatabaseInstance = DatabaseInstanceStr;
|
|
|
|
SyncUrl();
|
|
|
|
var state = await JsRuntime.LoadFromLocalStorage("Logs");
|
|
if (state != null)
|
|
{
|
|
_state = JsonUtils.FromJson<LogsPageState>(state) ?? new();
|
|
}
|
|
|
|
try
|
|
{
|
|
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
|
|
LogCategories = await UserSession.MongoDbAdminForAdminDatabase.GetLogCategories(cts.Token);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// ignore
|
|
}
|
|
|
|
StateHasChanged();
|
|
_ = Task.Run(Run);
|
|
}
|
|
|
|
private async Task Run()
|
|
{
|
|
|
|
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
|
|
|
|
try
|
|
{
|
|
IsReady = false; // Indicate that the process is starting
|
|
await InvokeAsync(() => JsRuntime.SaveToLocalStorage("Logs", JsonUtils.ToJson(_state), cts.Token));
|
|
await InvokeAsync(StateHasChanged);
|
|
|
|
var res = await UserSession.MongoDbAdminForAdminDatabase.GetLogs(token:cts.Token);
|
|
await Display(res);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
IsReady = true; // Indicate that the process has finished
|
|
await Display(e);
|
|
}
|
|
finally
|
|
{
|
|
IsReady = true; // Indicate that the process has finished
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
}
|
|
|
|
|
|
private Task Display(List<LogRecordModel> model)
|
|
{
|
|
Error = null;
|
|
|
|
model.Reverse();
|
|
Result = model;
|
|
|
|
AvailableCategories = model
|
|
.Select(x => x.Category)
|
|
.Distinct()
|
|
.OrderBy(x => x)
|
|
.ToList();
|
|
|
|
AvailableSeverity = model
|
|
.Select(x => x.Severity)
|
|
.Distinct()
|
|
.OrderBy(x => x)
|
|
.ToList();
|
|
|
|
return InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
|
|
private Task Display(Exception e)
|
|
{
|
|
Error = e;
|
|
Result.Clear();
|
|
return InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
private void SyncUrl()
|
|
{
|
|
var url = NavigationManager.BaseUri + $"user/logs/{Database}";
|
|
if (!string.IsNullOrWhiteSpace(DatabaseInstance))
|
|
url += $"/{DatabaseInstance}";
|
|
JsRuntime.InvokeAsync<string>("DashboardUtils.ChangeUrl", url);
|
|
}
|
|
|
|
private RenderFragment GetAttributes((dynamic Row, TableColumnControl Column) value)
|
|
{
|
|
LogRecordModel doc = value.Row;
|
|
|
|
var json = doc.Attr?.ToJson() ?? "";
|
|
if (json.Length > 100)
|
|
json = json[..100] + "...";
|
|
|
|
return @<span @onclick="@(() => OnCellClick(doc))">@json</span>;
|
|
}
|
|
|
|
private async Task OnCellClick(LogRecordModel doc)
|
|
{
|
|
var json = doc.ToJson(new () { Indent = true });
|
|
|
|
await ModalDialogUtils.ShowTextDialog(
|
|
Modal,
|
|
"Log event",
|
|
json, // Pass the JSON representation instead of the doc
|
|
"Press F11 to enter fullscreen mode. Use ESC to exit it."
|
|
);
|
|
}
|
|
|
|
}
|