feat: 完善健康检查界面

This commit is contained in:
Argo-Lenovo 2022-01-03 02:31:07 +08:00
parent 383eaaf14e
commit 9612e48bbb
4 changed files with 112 additions and 34 deletions

View File

@ -1 +1,30 @@
@page "/Admin/Healths"
@using Bootstrap.Security.Blazor.HealthChecks
<Card IsShadow="true">
<CardHeader>
<div class="d-flex align-items-center">
<span class="flex-fill">健康检查结果</span>
<span class="mx-3">@Duration</span>
<Tag Color="GetTagColor()" Icon="@GetTagIcon()">@GetTagText()</Tag>
</div>
</CardHeader>
<CardBody>
<Table TItem="HealthsCheckReportItem" OnQueryAsync="OnQueryAsync" ShowSkeleton="true" IsBordered="true" IsStriped="true" ShowExtendButtons="true">
<TableColumns>
<TableColumn @bind-Field="@context.Name" Lookup="@GetNameLookup()" Text="检查项"></TableColumn>
<TableColumn @bind-Field="@context.Description" Text="描述"></TableColumn>
<TableColumn @bind-Field="@context.Duration" Text="时长"></TableColumn>
<TableColumn @bind-Field="@context.Exception" Text="异常"></TableColumn>
<TableColumn @bind-Field="@context.Status" Text="检查结果">
<Template Context="v">
<Tag Icon="@GetTagIcon(v.Value)" Color="@GetTagColor(v.Value)">@GetTagText(v.Value)</Tag>
</Template>
</TableColumn>
</TableColumns>
<RowButtonTemplate>
<TableCellButton Color="Color.Primary" Icon="fa fa-info-circle" Text="明细" OnClick="@(() => OnRowButtonClick(context))" />
</RowButtonTemplate>
</Table>
</CardBody>
</Card>

View File

@ -1,4 +1,7 @@
using BootstrapAdmin.Web.Services;
using Bootstrap.Security.Blazor.HealthChecks;
using BootstrapAdmin.Web.Components;
using BootstrapAdmin.Web.Services;
using BootstrapAdmin.Web.Utils;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using System;
using System.Text.Json;
@ -16,32 +19,74 @@ public partial class Healths
[NotNull]
private NavigationManager? NavigationManager { get; set; }
/// <summary>
/// OnInitializedAsync
/// </summary>
/// <returns></returns>
protected override async Task OnInitializedAsync()
private TimeSpan Duration { get; set; }
private HealthStatus Status { get; set; }
[Inject]
[NotNull]
private DialogService? DialogService { get; set; }
[NotNull]
private HttpClient? Client { get; set; }
protected override void OnInitialized()
{
await base.OnInitializedAsync();
base.OnInitialized();
var client = HttpClientFactory.CreateClient();
client.BaseAddress = new Uri(NavigationManager.BaseUri);
var payload = await client.GetStringAsync("/Healths");
var serializeOption = new JsonSerializerOptions
{
PropertyNamingPolicy = null,
PropertyNameCaseInsensitive = true
};
serializeOption.Converters.Add(new StringToTimeSpanConverter());
var report = JsonSerializer.Deserialize<dynamic>(payload, serializeOption);
if (report != null)
{
foreach (var entry in report.Keys)
{
var item = report.Entries[entry];
}
}
Client = HttpClientFactory.CreateClient();
Client.BaseAddress = new Uri(NavigationManager.BaseUri);
}
private async Task<QueryData<HealthsCheckReportItem>> OnQueryAsync(QueryPageOptions options)
{
var payload = await Client.GetStringAsync("/Healths");
var report = HealthsCheckHelper.Parse(payload);
var ret = new QueryData<HealthsCheckReportItem>()
{
IsSorted = true,
IsFiltered = true,
IsSearch = true
};
ret.Items = report.Items;
Duration = report.Duration;
Status = report.Status;
return ret;
}
private static List<SelectedItem> GetNameLookup() => LookupHelper.GetCheckItems();
private string? GetTagText(HealthStatus? status = null) => (status ?? Status) switch
{
HealthStatus.Healthy => "健康",
HealthStatus.Degraded => "亚健康",
_ => "不健康"
};
private Color GetTagColor(HealthStatus? status = null) => (status ?? Status) switch
{
HealthStatus.Healthy => Color.Success,
HealthStatus.Degraded => Color.Warning,
_ => Color.Danger
};
private string? GetTagIcon(HealthStatus? status = null) => (status ?? Status) switch
{
HealthStatus.Healthy => "fa fa-check-circle",
HealthStatus.Degraded => "fa fa-exclamation-circle",
_ => "fa fa-times-circle"
};
private Task OnRowButtonClick(HealthsCheckReportItem item) => DialogService.Show(new DialogOption()
{
Title = $"{LookupHelper.GetCheckItems().FirstOrDefault(i => i.Value == item.Name)?.Text} - 详细数据",
IsScrolling = true,
Component = BootstrapDynamicComponent.CreateComponent<HealthCheckDetails>(new Dictionary<string, object?>
{
{ nameof(HealthCheckDetails.Data), item.Data }
})
});
}

View File

@ -15,4 +15,16 @@ static class LookupHelper
new SelectedItem("App", "应用程序"),
new SelectedItem("DB", "数据库")
};
public static List<SelectedItem> GetCheckItems() => new()
{
new("db", "数据库"),
new("environment", "环境变量"),
new("dotnet-runtime", "运行时"),
new("file", "文件系统"),
new("gc", "回收器"),
new("app-mem", "程序内存"),
new("sys-mem", "系统内存"),
new("Gitee", "Gitee")
};
}

View File

@ -45,14 +45,6 @@
height: calc(100vh - var(--bb-layout-header-height) - var(--bb-tab-header-height) - var(--bb-footer-height));
}
.table-scroll {
overflow: hidden;
}
.table-scroll:hover {
overflow-y: auto;
}
.tabs-body-content .error-stack {
height: calc(100vh - var(--bb-layout-header-height) - var(--bb-tab-header-height) - var(--bb-footer-height));
overflow: auto;