320 lines
9.3 KiB
Plaintext
320 lines
9.3 KiB
Plaintext
@page "/admin/db-stats"
|
|
@page "/admin/db-stats/{DatabaseStr}"
|
|
@page "/admin/db-stats/{DatabaseStr}/{DatabaseInstanceStr}"
|
|
@using ChartJs.Blazor
|
|
@using ChartJs.Blazor.BarChart
|
|
@using ChartJs.Blazor.BarChart.Axes
|
|
@using ChartJs.Blazor.Common.Axes
|
|
@using ChartJs.Blazor.Common.Enums
|
|
@using Rms.Risk.Mango.Pivot.Core.MongoDb
|
|
@using Rms.Risk.Mango.Services.Models
|
|
@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">Storage size</h3>
|
|
|
|
<AuthorizedOnly Policy="ReadAccess" Resource="@UserSession.Database">
|
|
@if (Error != null)
|
|
{
|
|
<ExceptionControl Exception="@Error"/>
|
|
}
|
|
|
|
<div class="chart-display @ChartClass">
|
|
<div class="chart-canvas ml-3">
|
|
<Chart Config="@_chartConfig"/>
|
|
</div>
|
|
</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 DatabaseStatsModel Result { get; set; } = new();
|
|
|
|
private string ChartClass => Result.Raw.Count == 0 || Error != null
|
|
? "d-none"
|
|
: ""
|
|
;
|
|
|
|
private static readonly string[] _colors = [
|
|
"rgba(255, 99, 132, 0.6)",
|
|
"rgba(255, 159, 64, 0.6)",
|
|
"rgba(255, 205, 86, 0.6)",
|
|
"rgba(75, 192, 192, 0.6)",
|
|
"rgba(54, 162, 235, 0.6)",
|
|
// "rgba(153, 102, 255, 0.4)",
|
|
// "rgba(201, 203, 207, 0.4)"
|
|
];
|
|
|
|
private string _unit = "B";
|
|
private double _divider = 1.0;
|
|
|
|
private readonly BarConfig _chartConfig = new()
|
|
{
|
|
Data =
|
|
{
|
|
Datasets =
|
|
{
|
|
new BarDataset<double>
|
|
{
|
|
Label = "Index used",
|
|
BackgroundColor = _colors[2],
|
|
BorderColor = _colors[2]
|
|
},
|
|
new BarDataset<double>
|
|
{
|
|
Label = "Index free",
|
|
BackgroundColor = _colors[3],
|
|
BorderColor = _colors[3]
|
|
},
|
|
new BarDataset<double>
|
|
{
|
|
Label = "Storage used",
|
|
BackgroundColor = _colors[0],
|
|
BorderColor = _colors[0]
|
|
},
|
|
new BarDataset<double>
|
|
{
|
|
Label = "Storage free",
|
|
BackgroundColor = _colors[1],
|
|
BorderColor = _colors[1]
|
|
},
|
|
// new BarDataset<double>
|
|
// {
|
|
// Label = "Other free",
|
|
// BackgroundColor = _colors[4],
|
|
// BorderColor = _colors[4]
|
|
// }
|
|
}
|
|
},
|
|
Options = new()
|
|
{
|
|
MaintainAspectRatio = true,
|
|
Responsive = true,
|
|
Legend = new()
|
|
{
|
|
Display = true,
|
|
Position = Position.Bottom
|
|
},
|
|
Scales = new()
|
|
{
|
|
YAxes = new List<CartesianAxis>
|
|
{
|
|
new BarLinearCartesianAxis
|
|
{
|
|
Stacked = true,
|
|
// OffsetGridLines = false,
|
|
// Offset = true,
|
|
// Display = AxisDisplay.False
|
|
}
|
|
},
|
|
XAxes = new List<CartesianAxis>
|
|
{
|
|
new BarCategoryAxis
|
|
{
|
|
Stacked = true,
|
|
// OffsetGridLines = false,
|
|
// Offset = false,
|
|
// Display = AxisDisplay.False,
|
|
// BarThickness = 45
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
protected override void OnAfterRender(bool firstRender)
|
|
{
|
|
if (!firstRender)
|
|
return;
|
|
|
|
if (string.IsNullOrWhiteSpace(DatabaseStr))
|
|
DatabaseStr = Database;
|
|
else
|
|
Database = DatabaseStr;
|
|
|
|
if (string.IsNullOrWhiteSpace(DatabaseInstanceStr))
|
|
DatabaseInstanceStr = DatabaseInstance;
|
|
else
|
|
DatabaseInstance = DatabaseInstanceStr;
|
|
|
|
SyncUrl();
|
|
StateHasChanged();
|
|
Task.Run(Run);
|
|
}
|
|
|
|
private async Task Run()
|
|
{
|
|
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
|
|
|
|
try
|
|
{
|
|
await InvokeAsync(StateHasChanged);
|
|
|
|
var res = await UserSession.MongoDbAdmin.DbStats(cts.Token);
|
|
await Display(res);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
await Display(e);
|
|
}
|
|
finally
|
|
{
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
}
|
|
|
|
private void UpdateChart(
|
|
DatabaseStatsModel data
|
|
)
|
|
{
|
|
_chartConfig.Data.XLabels.Clear();
|
|
|
|
foreach (var key in data.Raw.Keys)
|
|
{
|
|
var parts = key.Split('/');
|
|
_chartConfig.Data.XLabels.Add(parts[0]); // replica set name
|
|
}
|
|
|
|
var dataMax = data.Raw.Values.Max(x => x.StorageSize+x.IndexSize);
|
|
|
|
// Decide unit
|
|
if (dataMax > 1024 * 1024 * 1024) // > 1 GB
|
|
{
|
|
_unit = "GB";
|
|
_divider = 1024 * 1024 * 1024;
|
|
}
|
|
else
|
|
{
|
|
_unit = "MB";
|
|
_divider = 1024 * 1024;
|
|
}
|
|
|
|
var indexUsed = (BarDataset<double>)_chartConfig.Data.Datasets[0];
|
|
var indexFree = (BarDataset<double>)_chartConfig.Data.Datasets[1];
|
|
var storageUsed = (BarDataset<double>)_chartConfig.Data.Datasets[2];
|
|
var storageFree = (BarDataset<double>)_chartConfig.Data.Datasets[3];
|
|
// var otherFree = (BarDataset<double>)_chartConfig.Data.Datasets[4];
|
|
|
|
storageUsed.Clear();
|
|
storageFree.Clear();
|
|
indexUsed .Clear();
|
|
indexFree .Clear();
|
|
// otherFree .Clear();
|
|
|
|
storageUsed.AddRange(data.Raw.Values.Select(x => (x.StorageSize - x.FreeStorageSize) / _divider));
|
|
storageFree.AddRange(data.Raw.Values.Select(x => x.FreeStorageSize / _divider));
|
|
indexUsed .AddRange(data.Raw.Values.Select(x => (x.IndexSize - x.IndexFreeStorageSize) / _divider));
|
|
indexFree .AddRange(data.Raw.Values.Select(x => x.IndexFreeStorageSize / _divider));
|
|
// otherFree.AddRange(data.Raw.Values.Select(x => (x.FsUsedSize - x.StorageSize - x.IndexSize) / _divider));
|
|
|
|
_chartConfig.Data.Datasets.Add(storageUsed);
|
|
_chartConfig.Data.Datasets.Add(storageFree);
|
|
_chartConfig.Data.Datasets.Add(indexUsed );
|
|
_chartConfig.Data.Datasets.Add(indexFree );
|
|
// _chartConfig.Data.Datasets.Add(otherFree );
|
|
|
|
|
|
_chartConfig.Options.Scales.YAxes.Clear();
|
|
_chartConfig.Options.Scales.YAxes.Add(new BarLinearCartesianAxis
|
|
{
|
|
Stacked = true,
|
|
ScaleLabel = new ()
|
|
{
|
|
Display = true,
|
|
LabelString = $"Size {_unit}"
|
|
},
|
|
Ticks = new ()
|
|
{
|
|
Min = 0.0,
|
|
Max = dataMax / _divider,
|
|
}
|
|
});
|
|
}
|
|
|
|
private Task Display(DatabaseStatsModel model)
|
|
{
|
|
Error = null;
|
|
Result = model;
|
|
|
|
UpdateChart(model);
|
|
|
|
return InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
|
|
private Task Display(Exception e)
|
|
{
|
|
Error = e;
|
|
Result.Raw.Clear();
|
|
return InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
private void SyncUrl()
|
|
{
|
|
var url = NavigationManager.BaseUri + $"admin/db-stats/{Database}";
|
|
if (!string.IsNullOrWhiteSpace(DatabaseInstance))
|
|
url += $"/{DatabaseInstance}";
|
|
JsRuntime.InvokeAsync<string>("DashboardUtils.ChangeUrl", url);
|
|
}
|
|
|
|
}
|