feat: 完善健康检查界面
This commit is contained in:
parent
383eaaf14e
commit
9612e48bbb
|
@ -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>
|
||||
|
|
|
@ -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 }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue