From 631c1bd5490f73fd3ae616f2bcb8adc47c096794 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 13:39:18 +0800 Subject: [PATCH 01/14] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=81=A5?= =?UTF-8?q?=E5=BA=B7=E6=A3=80=E6=9F=A5=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bootstrap.Admin/HealthChecks/DBHealthCheck.cs | 27 +++++++++++++++++++ .../HealthChecksAppBuilderExtensions.cs | 19 +++++++++++++ .../HealthChecksBuilderExtensions.cs | 19 +++++++++++++ Bootstrap.Admin/Startup.cs | 2 ++ 4 files changed, 67 insertions(+) create mode 100644 Bootstrap.Admin/HealthChecks/DBHealthCheck.cs create mode 100644 Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs create mode 100644 Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs diff --git a/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs b/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs new file mode 100644 index 00000000..621e1b7a --- /dev/null +++ b/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs @@ -0,0 +1,27 @@ +using Microsoft.Extensions.Diagnostics.HealthChecks; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Bootstrap.Admin.HealthChecks +{ + /// + /// 数据库检查 + /// + public class DBHealthCheck : IHealthCheck + { + /// + /// 异步检查方法 + /// + /// + /// + /// + public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) + { + var data = new Dictionary(); + data.Add("Test1", "Test1"); + data.Add("Test2", "Test2"); + return Task.FromResult(HealthCheckResult.Healthy("Ok", data)); + } + } +} diff --git a/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs b/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs new file mode 100644 index 00000000..82032a2d --- /dev/null +++ b/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs @@ -0,0 +1,19 @@ +namespace Microsoft.AspNetCore.Builder +{ + /// + /// BootstrapAdmin 健康检查扩展类 + /// + public static class HealthChecksAppBuilderExtensions + { + /// + /// + /// + /// + /// + public static IApplicationBuilder UseBootstrapHealthChecks(this IApplicationBuilder app) + { + app.UseHealthChecks("Healths"); + return app; + } + } +} diff --git a/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs new file mode 100644 index 00000000..260a38cb --- /dev/null +++ b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs @@ -0,0 +1,19 @@ +namespace Microsoft.Extensions.DependencyInjection +{ + /// + /// 健康检查扩展类 + /// + public static class HealthChecksBuilderExtensions + { + /// + /// 添加 BootstrapAdmin 健康检查 + /// + /// + /// + public static IHealthChecksBuilder AddBootstrapAdminHealthChecks(this IHealthChecksBuilder builder) + { + builder.AddCheck("db"); + return builder; + } + } +} diff --git a/Bootstrap.Admin/Startup.cs b/Bootstrap.Admin/Startup.cs index 5715b9eb..b880f414 100644 --- a/Bootstrap.Admin/Startup.cs +++ b/Bootstrap.Admin/Startup.cs @@ -64,6 +64,7 @@ namespace Bootstrap.Admin services.AddSwagger(); services.AddButtonAuthorization(); services.AddDemoTask(); + services.AddHealthChecks().AddBootstrapAdminHealthChecks(); services.AddMvc(options => { options.Filters.Add(); @@ -107,6 +108,7 @@ namespace Bootstrap.Admin app.UseHttpsRedirection(); app.UseResponseCompression(); app.UseStaticFiles(); + app.UseBootstrapHealthChecks(); app.UseBootstrapAdminAuthentication(RoleHelper.RetrievesByUserName, RoleHelper.RetrievesByUrl, AppHelper.RetrievesByUserName); app.UseOnlineUsers(callback: TraceHelper.Save); app.UseCacheManager(); From a191a9e383b380610e7c38b2affea14af5f78afd Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 14:19:27 +0800 Subject: [PATCH 02/14] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89json=E6=A0=BC=E5=BC=8F=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E5=81=A5=E5=BA=B7=E6=A3=80=E6=9F=A5=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bootstrap.Admin/HealthChecks/DBHealthCheck.cs | 17 +++++++++------ .../HealthChecksAppBuilderExtensions.cs | 21 +++++++++++++++---- .../HealthChecksBuilderExtensions.cs | 6 ++++-- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs b/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs index 621e1b7a..736f56f5 100644 --- a/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs +++ b/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs @@ -1,7 +1,10 @@ -using Microsoft.Extensions.Diagnostics.HealthChecks; -using System.Collections.Generic; +using Bootstrap.DataAccess; +using Bootstrap.Security; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using System.Linq; using System.Threading; using System.Threading.Tasks; +using Task = System.Threading.Tasks.Task; namespace Bootstrap.Admin.HealthChecks { @@ -18,10 +21,12 @@ namespace Bootstrap.Admin.HealthChecks /// public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { - var data = new Dictionary(); - data.Add("Test1", "Test1"); - data.Add("Test2", "Test2"); - return Task.FromResult(HealthCheckResult.Healthy("Ok", data)); + using (var db = DbManager.Create()) + { + var connStr = db.ConnectionString; + var dicts = db.Fetch("Select * from Dicts"); + return dicts.Any() ? Task.FromResult(HealthCheckResult.Healthy("Ok")) : Task.FromResult(HealthCheckResult.Degraded("No init data in DB")); + } } } } diff --git a/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs b/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs index 82032a2d..3b07e2f5 100644 --- a/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs +++ b/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs @@ -1,4 +1,8 @@ -namespace Microsoft.AspNetCore.Builder +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.AspNetCore.Http; +using Newtonsoft.Json; + +namespace Microsoft.AspNetCore.Builder { /// /// BootstrapAdmin 健康检查扩展类 @@ -6,13 +10,22 @@ public static class HealthChecksAppBuilderExtensions { /// - /// + /// 启用健康检查 /// /// + /// /// - public static IApplicationBuilder UseBootstrapHealthChecks(this IApplicationBuilder app) + public static IApplicationBuilder UseBootstrapHealthChecks(this IApplicationBuilder app, PathString path = default) { - app.UseHealthChecks("Healths"); + if (path == default) path = "/Healths"; + app.UseHealthChecks(path, new HealthCheckOptions() + { + ResponseWriter = (context, report) => + { + context.Response.ContentType = "application/json"; + return context.Response.WriteAsync(JsonConvert.SerializeObject(report)); + } + }); return app; } } diff --git a/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs index 260a38cb..d5352528 100644 --- a/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs +++ b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs @@ -1,4 +1,6 @@ -namespace Microsoft.Extensions.DependencyInjection +using Bootstrap.Admin.HealthChecks; + +namespace Microsoft.Extensions.DependencyInjection { /// /// 健康检查扩展类 @@ -12,7 +14,7 @@ /// public static IHealthChecksBuilder AddBootstrapAdminHealthChecks(this IHealthChecksBuilder builder) { - builder.AddCheck("db"); + builder.AddCheck("db"); return builder; } } From dd8aaa633c65428b56febf1bac3547867e7e4a68 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 14:39:35 +0800 Subject: [PATCH 03/14] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=A3=80=E6=9F=A5=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bootstrap.Admin/HealthChecks/DBHealthCheck.cs | 2 +- Bootstrap.Admin/HealthChecks/FileHealCheck.cs | 44 +++++++++++++++++++ .../HealthChecksBuilderExtensions.cs | 1 + 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 Bootstrap.Admin/HealthChecks/FileHealCheck.cs diff --git a/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs b/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs index 736f56f5..4bf090ea 100644 --- a/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs +++ b/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs @@ -9,7 +9,7 @@ using Task = System.Threading.Tasks.Task; namespace Bootstrap.Admin.HealthChecks { /// - /// 数据库检查 + /// 数据库检查类 /// public class DBHealthCheck : IHealthCheck { diff --git a/Bootstrap.Admin/HealthChecks/FileHealCheck.cs b/Bootstrap.Admin/HealthChecks/FileHealCheck.cs new file mode 100644 index 00000000..ef5ed450 --- /dev/null +++ b/Bootstrap.Admin/HealthChecks/FileHealCheck.cs @@ -0,0 +1,44 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace Bootstrap.Admin.HealthChecks +{ + /// + /// 文件健康检查类 + /// + public class FileHealCheck : IHealthCheck + { + private readonly IHostingEnvironment _env; + /// + /// 构造函数 + /// + /// + public FileHealCheck(IHostingEnvironment env) + { + _env = env; + } + + /// + /// 异步检查方法 + /// + /// + /// + /// + public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) + { + var file = _env.IsDevelopment() ? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Longbow.lic") : Path.Combine(_env.ContentRootPath, "Longbow.lic"); + var data = new Dictionary(); + data.Add("ContentRootPath", _env.ContentRootPath); + data.Add("WebRootPath", _env.WebRootPath); + data.Add("ApplicationName", _env.ApplicationName); + data.Add("EnvironmentName", _env.EnvironmentName); + data.Add("CheckFile", file); + return Task.FromResult(File.Exists(file) ? HealthCheckResult.Healthy("Ok", data) : HealthCheckResult.Unhealthy($"Missing file {file}", null, data)); + } + } +} diff --git a/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs index d5352528..f01887f9 100644 --- a/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs +++ b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs @@ -15,6 +15,7 @@ namespace Microsoft.Extensions.DependencyInjection public static IHealthChecksBuilder AddBootstrapAdminHealthChecks(this IHealthChecksBuilder builder) { builder.AddCheck("db"); + builder.AddCheck("file"); return builder; } } From c0261e1ce3211955cb4b5df3a46d6be8eded5e9d Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 14:54:26 +0800 Subject: [PATCH 04/14] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0GC=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bootstrap.Admin/HealthChecks/GCHealthCheck.cs | 38 +++++++++++++++++++ .../HealthChecksBuilderExtensions.cs | 1 + 2 files changed, 39 insertions(+) create mode 100644 Bootstrap.Admin/HealthChecks/GCHealthCheck.cs diff --git a/Bootstrap.Admin/HealthChecks/GCHealthCheck.cs b/Bootstrap.Admin/HealthChecks/GCHealthCheck.cs new file mode 100644 index 00000000..334755f2 --- /dev/null +++ b/Bootstrap.Admin/HealthChecks/GCHealthCheck.cs @@ -0,0 +1,38 @@ +using Microsoft.Extensions.Diagnostics.HealthChecks; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Bootstrap.Admin.HealthChecks +{ + /// + /// 内存状态检查其 + /// + public class GCHealthCheck : IHealthCheck + { + /// + /// 构造函数 + /// + /// + /// + /// + public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) + { + // Include GC information in the reported diagnostics. + var allocated = GC.GetTotalMemory(forceFullCollection: false); + var data = new Dictionary() + { + { "AllocatedMBytes", allocated / 1024 / 1024 }, + { "Gen0Collections", GC.CollectionCount(0) }, + { "Gen1Collections", GC.CollectionCount(1) }, + { "Gen2Collections", GC.CollectionCount(2) }, + }; + + var status = (allocated < 100000) ? + HealthStatus.Healthy : HealthStatus.Unhealthy; + + return Task.FromResult(new HealthCheckResult(status, data: data)); + } + } +} diff --git a/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs index f01887f9..5c0d0728 100644 --- a/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs +++ b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs @@ -16,6 +16,7 @@ namespace Microsoft.Extensions.DependencyInjection { builder.AddCheck("db"); builder.AddCheck("file"); + builder.AddCheck("gc"); return builder; } } From fd49fd178542ba19530261eae89bae2a8ceca0ba Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 15:24:23 +0800 Subject: [PATCH 05/14] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=86=85=E5=AD=98=E6=83=85=E5=86=B5=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HealthChecksBuilderExtensions.cs | 1 + .../HealthChecks/MemoryHealthCheck.cs | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 Bootstrap.Admin/HealthChecks/MemoryHealthCheck.cs diff --git a/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs index 5c0d0728..44f81365 100644 --- a/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs +++ b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs @@ -17,6 +17,7 @@ namespace Microsoft.Extensions.DependencyInjection builder.AddCheck("db"); builder.AddCheck("file"); builder.AddCheck("gc"); + builder.AddCheck("mem"); return builder; } } diff --git a/Bootstrap.Admin/HealthChecks/MemoryHealthCheck.cs b/Bootstrap.Admin/HealthChecks/MemoryHealthCheck.cs new file mode 100644 index 00000000..1d3aef58 --- /dev/null +++ b/Bootstrap.Admin/HealthChecks/MemoryHealthCheck.cs @@ -0,0 +1,34 @@ +using Microsoft.Extensions.Diagnostics.HealthChecks; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; + +namespace Bootstrap.Admin.HealthChecks +{ + /// + /// 内存检查器 + /// + public class MemoryHealthCheck : IHealthCheck + { + /// + /// 构造函数 + /// + /// + /// + /// + public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) + { + var process = Process.GetCurrentProcess(); + var data = new Dictionary() + { + { "Id", process.Id }, + { "WorkingSet", process.WorkingSet64 }, + { "PrivateMemory", process.PrivateMemorySize64 }, + { "VirtualMemory", process.VirtualMemorySize64 }, + }; + + return Task.FromResult(HealthCheckResult.Healthy("Ok", data)); + } + } +} From 9e82a5d272c6017ee8e10fa8d67ea05afe718d94 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 15:55:26 +0800 Subject: [PATCH 06/14] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=94=B9=20xml=20?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bootstrap.Admin/HealthChecks/GCHealthCheck.cs | 2 +- Bootstrap.Admin/HealthChecks/MemoryHealthCheck.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Bootstrap.Admin/HealthChecks/GCHealthCheck.cs b/Bootstrap.Admin/HealthChecks/GCHealthCheck.cs index 334755f2..3476e24b 100644 --- a/Bootstrap.Admin/HealthChecks/GCHealthCheck.cs +++ b/Bootstrap.Admin/HealthChecks/GCHealthCheck.cs @@ -12,7 +12,7 @@ namespace Bootstrap.Admin.HealthChecks public class GCHealthCheck : IHealthCheck { /// - /// 构造函数 + /// 异步检查方法 /// /// /// diff --git a/Bootstrap.Admin/HealthChecks/MemoryHealthCheck.cs b/Bootstrap.Admin/HealthChecks/MemoryHealthCheck.cs index 1d3aef58..6aaba559 100644 --- a/Bootstrap.Admin/HealthChecks/MemoryHealthCheck.cs +++ b/Bootstrap.Admin/HealthChecks/MemoryHealthCheck.cs @@ -12,7 +12,7 @@ namespace Bootstrap.Admin.HealthChecks public class MemoryHealthCheck : IHealthCheck { /// - /// 构造函数 + /// 异步检查方法 /// /// /// From c4aee7cc19b3940a3dd89ac96ad1d110956d0fec Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 15:55:55 +0800 Subject: [PATCH 07/14] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20Gitee=20?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HealthChecks/GiteeHttpHealthCheck.cs | 52 +++++++++++++++++++ .../HealthChecksBuilderExtensions.cs | 1 + 2 files changed, 53 insertions(+) create mode 100644 Bootstrap.Admin/HealthChecks/GiteeHttpHealthCheck.cs diff --git a/Bootstrap.Admin/HealthChecks/GiteeHttpHealthCheck.cs b/Bootstrap.Admin/HealthChecks/GiteeHttpHealthCheck.cs new file mode 100644 index 00000000..32db6cf7 --- /dev/null +++ b/Bootstrap.Admin/HealthChecks/GiteeHttpHealthCheck.cs @@ -0,0 +1,52 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace Bootstrap.Admin.HealthChecks +{ + /// + /// Gitee 接口检查器 + /// + public class GiteeHttpHealthCheck : IHealthCheck + { + private readonly HttpClient _client; + /// + /// 构造函数 + /// + /// + /// + public GiteeHttpHealthCheck(IHttpClientFactory factory, IHttpContextAccessor accessor) + { + _client = factory.CreateClient(); + _client.BaseAddress = new Uri($"{accessor.HttpContext.Request.Scheme}://{accessor.HttpContext.Request.Host}/{accessor.HttpContext.Request.PathBase}"); + } + + /// + /// 异步检查方法 + /// + /// + /// + /// + public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) + { + var urls = new string[] { "Issues", "Pulls", "Releases", "Builds" }; + var data = new Dictionary(); + + var sw = Stopwatch.StartNew(); + foreach (var url in urls) + { + sw.Restart(); + await _client.GetStringAsync($"api/Gitee/{url}").ConfigureAwait(false); + sw.Stop(); + data.Add(url, sw.Elapsed); + } + + return HealthCheckResult.Healthy("Ok", data); + } + } +} diff --git a/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs index 44f81365..2bdd2b93 100644 --- a/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs +++ b/Bootstrap.Admin/HealthChecks/HealthChecksBuilderExtensions.cs @@ -18,6 +18,7 @@ namespace Microsoft.Extensions.DependencyInjection builder.AddCheck("file"); builder.AddCheck("gc"); builder.AddCheck("mem"); + builder.AddCheck("Gitee"); return builder; } } From 35b291fa06692f00cf7cf4866e2ed3a9de2cbfcf Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 16:42:04 +0800 Subject: [PATCH 08/14] =?UTF-8?q?style:=20=E9=94=99=E8=AF=AF=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=20a=20=E9=93=BE=E6=8E=A5=E5=A2=9E=E5=8A=A0=20point=20?= =?UTF-8?q?=E9=BC=A0=E6=A0=87=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bootstrap.Admin/wwwroot/css/error.css | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Bootstrap.Admin/wwwroot/css/error.css b/Bootstrap.Admin/wwwroot/css/error.css index 94e1db06..9aa8ff10 100644 --- a/Bootstrap.Admin/wwwroot/css/error.css +++ b/Bootstrap.Admin/wwwroot/css/error.css @@ -28,8 +28,12 @@ img { text-align: left; } -a, a:hover, a:focus { - text-decoration: none; - outline: none; - color: #371ed4; +a { + cursor: pointer; } + + a, a:hover, a:focus { + text-decoration: none; + outline: none; + color: #371ed4; + } From 1e8ef647f7d1979a8bacd2b857c6e721c9300be6 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 17:30:56 +0800 Subject: [PATCH 09/14] =?UTF-8?q?refactor:=20=E6=9B=B4=E6=94=B9=E5=81=A5?= =?UTF-8?q?=E5=BA=B7=E6=A3=80=E6=9F=A5=E8=BF=94=E5=9B=9E=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HealthChecks/HealthChecksAppBuilderExtensions.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs b/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs index 3b07e2f5..f84c4b25 100644 --- a/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs +++ b/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Diagnostics.HealthChecks; using Newtonsoft.Json; namespace Microsoft.AspNetCore.Builder @@ -24,6 +25,12 @@ namespace Microsoft.AspNetCore.Builder { context.Response.ContentType = "application/json"; return context.Response.WriteAsync(JsonConvert.SerializeObject(report)); + }, + ResultStatusCodes = + { + [HealthStatus.Healthy] = StatusCodes.Status200OK, + [HealthStatus.Degraded] = StatusCodes.Status200OK, + [HealthStatus.Unhealthy] = StatusCodes.Status200OK } }); return app; From 088ff671aeb443352c85b01e58235acdd1a8cc16 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 17:31:30 +0800 Subject: [PATCH 10/14] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=90=8E?= =?UTF-8?q?=E5=8F=B0=E7=AE=A1=E7=90=86=E5=81=A5=E5=BA=B7=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/AdminController.cs | 6 ++++ Bootstrap.Admin/Views/Admin/Healths.cshtml | 32 +++++++++++++++++++ Bootstrap.Admin/wwwroot/js/healths.js | 23 +++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 Bootstrap.Admin/Views/Admin/Healths.cshtml create mode 100644 Bootstrap.Admin/wwwroot/js/healths.js diff --git a/Bootstrap.Admin/Controllers/AdminController.cs b/Bootstrap.Admin/Controllers/AdminController.cs index a8990649..9d009c90 100644 --- a/Bootstrap.Admin/Controllers/AdminController.cs +++ b/Bootstrap.Admin/Controllers/AdminController.cs @@ -71,6 +71,12 @@ namespace Bootstrap.Admin.Controllers /// public ActionResult FAIcon() => View(new NavigatorBarModel(this)); + /// + /// + /// + /// + public ActionResult Healths() => View(new NavigatorBarModel(this)); + /// /// /// diff --git a/Bootstrap.Admin/Views/Admin/Healths.cshtml b/Bootstrap.Admin/Views/Admin/Healths.cshtml new file mode 100644 index 00000000..c2b205a1 --- /dev/null +++ b/Bootstrap.Admin/Views/Admin/Healths.cshtml @@ -0,0 +1,32 @@ +@model NavigatorBarModel +@{ + ViewBag.Title = "健康检查"; +} +@section css { + + + + + + +} +@section javascript { + + + + + + + + + +} +
+
+ 健康检查结果 +
+
+
耗时:0.01
+
+
+
diff --git a/Bootstrap.Admin/wwwroot/js/healths.js b/Bootstrap.Admin/wwwroot/js/healths.js new file mode 100644 index 00000000..3a93eec0 --- /dev/null +++ b/Bootstrap.Admin/wwwroot/js/healths.js @@ -0,0 +1,23 @@ +$(function () { + var $table = $('table').smartTable({ + sidePagination: "client", + showToggle: false, + showRefresh: false, + showColumns: false, + columns: [ + { title: "分类", field: "name", sortable: true }, + { title: "描述", field: "Description", sortable: true }, + { title: "异常信息", field: "Exception", sortable: true }, + { title: "明细数据", field: "Data", sortable: true }, + { title: "检查结果", field: "Status", sortable: false }, + { title: "耗时", field: "Duration", sortable: true } + ] + }); + + $.bc({ + url: 'healths', + callback: function (result) { + console.log(result); + } + }); +}); \ No newline at end of file From 03d5d74add829463c653973c4d6bd37066199167 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 20:10:23 +0800 Subject: [PATCH 11/14] =?UTF-8?q?feat:=20=E5=81=A5=E5=BA=B7=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E9=A1=B5=E9=9D=A2=E5=A2=9E=E5=8A=A0=E6=98=8E=E7=BB=86?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bootstrap.Admin/HealthChecks/GCHealthCheck.cs | 6 +-- .../HealthChecksAppBuilderExtensions.cs | 2 +- Bootstrap.Admin/Views/Admin/Healths.cshtml | 2 +- Bootstrap.Admin/wwwroot/css/theme.css | 8 +++ Bootstrap.Admin/wwwroot/js/healths.js | 51 ++++++++++++++++--- 5 files changed, 55 insertions(+), 14 deletions(-) diff --git a/Bootstrap.Admin/HealthChecks/GCHealthCheck.cs b/Bootstrap.Admin/HealthChecks/GCHealthCheck.cs index 3476e24b..9692f45c 100644 --- a/Bootstrap.Admin/HealthChecks/GCHealthCheck.cs +++ b/Bootstrap.Admin/HealthChecks/GCHealthCheck.cs @@ -28,11 +28,7 @@ namespace Bootstrap.Admin.HealthChecks { "Gen1Collections", GC.CollectionCount(1) }, { "Gen2Collections", GC.CollectionCount(2) }, }; - - var status = (allocated < 100000) ? - HealthStatus.Healthy : HealthStatus.Unhealthy; - - return Task.FromResult(new HealthCheckResult(status, data: data)); + return Task.FromResult(HealthCheckResult.Healthy("OK", data)); } } } diff --git a/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs b/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs index f84c4b25..f76ae8d2 100644 --- a/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs +++ b/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Builder ResponseWriter = (context, report) => { context.Response.ContentType = "application/json"; - return context.Response.WriteAsync(JsonConvert.SerializeObject(report)); + return context.Response.WriteAsync(JsonConvert.SerializeObject(new { report.Entries.Keys, Report = report })); }, ResultStatusCodes = { diff --git a/Bootstrap.Admin/Views/Admin/Healths.cshtml b/Bootstrap.Admin/Views/Admin/Healths.cshtml index c2b205a1..d87a17c1 100644 --- a/Bootstrap.Admin/Views/Admin/Healths.cshtml +++ b/Bootstrap.Admin/Views/Admin/Healths.cshtml @@ -26,7 +26,7 @@ 健康检查结果
-
耗时:0.01
+
耗时:--
diff --git a/Bootstrap.Admin/wwwroot/css/theme.css b/Bootstrap.Admin/wwwroot/css/theme.css index acc8d797..ce2102eb 100644 --- a/Bootstrap.Admin/wwwroot/css/theme.css +++ b/Bootstrap.Admin/wwwroot/css/theme.css @@ -709,11 +709,19 @@ input.pending { min-width: unset; } +.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^="bottom"] .popover-header::before { + border-bottom: 0; +} + .popover { max-width: 320px; padding: 0; } +.popover-body .bootstrap-table { + margin: 0.25rem 0; +} + .popover-content { max-height: 240px; overflow-y: auto; diff --git a/Bootstrap.Admin/wwwroot/js/healths.js b/Bootstrap.Admin/wwwroot/js/healths.js index 3a93eec0..2b7c8886 100644 --- a/Bootstrap.Admin/wwwroot/js/healths.js +++ b/Bootstrap.Admin/wwwroot/js/healths.js @@ -1,23 +1,60 @@ $(function () { + var healthStatus = ["不健康", "亚健康", "健康"]; + var StatusFormatter = function (value) { + return healthStatus[value]; + }; + + var cate = { "db": "数据库", "file": "组件文件", "mem": "内存", "Gitee": "Gitee 接口", "gc": "垃圾回收器" }; + var CategoryFormatter = function (value) { + return cate[value]; + }; + var $table = $('table').smartTable({ sidePagination: "client", showToggle: false, showRefresh: false, showColumns: false, columns: [ - { title: "分类", field: "name", sortable: true }, - { title: "描述", field: "Description", sortable: true }, - { title: "异常信息", field: "Exception", sortable: true }, - { title: "明细数据", field: "Data", sortable: true }, - { title: "检查结果", field: "Status", sortable: false }, - { title: "耗时", field: "Duration", sortable: true } + { title: "分类", field: "Name", formatter: CategoryFormatter }, + { title: "描述", field: "Description" }, + { title: "异常信息", field: "Exception" }, + { title: "耗时", field: "Duration" }, + { title: "检查结果", field: "Status", formatter: StatusFormatter }, + { + title: "明细数据", field: "Data", formatter: function (value, row, index) { + return ''; + }, + events: { + 'click .detail': function (e, value, row, index) { + if ($.isEmptyObject(row.Data)) return; + + var $button = $(e.currentTarget); + if (!$button.data($.fn.popover.Constructor.DATA_KEY)) { + var content = $.map(row.Data, function (v, name) { + return $.format("{0}{1}", name, v); + }).join(""); + content = $.format('
{0}
检查项
检查值
', content); + $button.popover({ title: cate[row.Name], html: true, content: content, placement: $(window).width() < 768 ? "bottom" : "left" }); + } + $button.popover('show'); + } + } + } ] }); + $table.bootstrapTable('showLoading'); + $('#checkTotalEplsed').text('--'); $.bc({ url: 'healths', callback: function (result) { - console.log(result); + var data = $.map(result.Keys, function (name) { + return { Name: name, Duration: result.Report.Entries[name].Duration, Status: result.Report.Entries[name].Status, Exception: result.Report.Entries[name].Exception, Description: result.Report.Entries[name].Description, Data: result.Report.Entries[name].Data }; + }); + $table.bootstrapTable('hideLoading'); + $table.bootstrapTable('load', data); + $('#checkTotalEplsed').text(result.Report.TotalDuration); + $.footer(); } }); }); \ No newline at end of file From fb30940a6b99807c58a46fec3fff1d7769d34e87 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 20:22:51 +0800 Subject: [PATCH 12/14] =?UTF-8?q?style:=20popover=20=E5=86=85=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E7=AC=AC=E4=B8=80=E8=A1=8C=E8=AE=BE=E7=BD=AE=E4=B8=8D?= =?UTF-8?q?=E6=8D=A2=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bootstrap.Admin/Views/Admin/Healths.cshtml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Bootstrap.Admin/Views/Admin/Healths.cshtml b/Bootstrap.Admin/Views/Admin/Healths.cshtml index d87a17c1..6975c250 100644 --- a/Bootstrap.Admin/Views/Admin/Healths.cshtml +++ b/Bootstrap.Admin/Views/Admin/Healths.cshtml @@ -9,6 +9,11 @@ + } @section javascript { From ee702157dbbce6fda6b2b74e47e1fd474f85bfef Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Tue, 13 Aug 2019 20:23:28 +0800 Subject: [PATCH 13/14] =?UTF-8?q?refactor:=20=E7=B2=BE=E7=AE=80=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=BF=AE=E6=AD=A3=E6=A3=80=E6=9F=A5=E9=A1=B9=E9=A1=BA?= =?UTF-8?q?=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bootstrap.Admin/HealthChecks/DBHealthCheck.cs | 9 ++++++++- Bootstrap.Admin/HealthChecks/FileHealCheck.cs | 14 ++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs b/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs index 4bf090ea..51f7efed 100644 --- a/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs +++ b/Bootstrap.Admin/HealthChecks/DBHealthCheck.cs @@ -1,6 +1,7 @@ using Bootstrap.DataAccess; using Bootstrap.Security; using Microsoft.Extensions.Diagnostics.HealthChecks; +using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -25,7 +26,13 @@ namespace Bootstrap.Admin.HealthChecks { var connStr = db.ConnectionString; var dicts = db.Fetch("Select * from Dicts"); - return dicts.Any() ? Task.FromResult(HealthCheckResult.Healthy("Ok")) : Task.FromResult(HealthCheckResult.Degraded("No init data in DB")); + var data = new Dictionary() + { + { "ConnectionString", connStr }, + { "DbType", db.Provider.GetType().Name }, + { "Dicts", dicts.Count } + }; + return dicts.Any() ? Task.FromResult(HealthCheckResult.Healthy("Ok", data)) : Task.FromResult(HealthCheckResult.Degraded("No init data in DB")); } } } diff --git a/Bootstrap.Admin/HealthChecks/FileHealCheck.cs b/Bootstrap.Admin/HealthChecks/FileHealCheck.cs index ef5ed450..591409f9 100644 --- a/Bootstrap.Admin/HealthChecks/FileHealCheck.cs +++ b/Bootstrap.Admin/HealthChecks/FileHealCheck.cs @@ -32,12 +32,14 @@ namespace Bootstrap.Admin.HealthChecks public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { var file = _env.IsDevelopment() ? Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Longbow.lic") : Path.Combine(_env.ContentRootPath, "Longbow.lic"); - var data = new Dictionary(); - data.Add("ContentRootPath", _env.ContentRootPath); - data.Add("WebRootPath", _env.WebRootPath); - data.Add("ApplicationName", _env.ApplicationName); - data.Add("EnvironmentName", _env.EnvironmentName); - data.Add("CheckFile", file); + var data = new Dictionary + { + { "ApplicationName", _env.ApplicationName }, + { "EnvironmentName", _env.EnvironmentName }, + { "ContentRootPath", _env.ContentRootPath }, + { "WebRootPath", _env.WebRootPath }, + { "CheckFile", file } + }; return Task.FromResult(File.Exists(file) ? HealthCheckResult.Healthy("Ok", data) : HealthCheckResult.Unhealthy($"Missing file {file}", null, data)); } } From 505c560ed6dfb07580b706cf2fade3ec977209a2 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 14 Aug 2019 10:17:21 +0800 Subject: [PATCH 14/14] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20healths-ui?= =?UTF-8?q?=20=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HealthChecksAppBuilderExtensions.cs | 6 +++ Bootstrap.Admin/wwwroot/html/Healths-UI.html | 49 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 Bootstrap.Admin/wwwroot/html/Healths-UI.html diff --git a/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs b/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs index f76ae8d2..3718ebc1 100644 --- a/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs +++ b/Bootstrap.Admin/HealthChecks/HealthChecksAppBuilderExtensions.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Diagnostics.HealthChecks; using Newtonsoft.Json; +using System.Threading.Tasks; namespace Microsoft.AspNetCore.Builder { @@ -33,6 +34,11 @@ namespace Microsoft.AspNetCore.Builder [HealthStatus.Unhealthy] = StatusCodes.Status200OK } }); + app.UseWhen(context => context.Request.Path == "/healths-ui", builder => builder.Run(request => + { + request.Response.Redirect("/html/Healths-UI.html"); + return Task.CompletedTask; + })); return app; } } diff --git a/Bootstrap.Admin/wwwroot/html/Healths-UI.html b/Bootstrap.Admin/wwwroot/html/Healths-UI.html new file mode 100644 index 00000000..d9ae290f --- /dev/null +++ b/Bootstrap.Admin/wwwroot/html/Healths-UI.html @@ -0,0 +1,49 @@ + + + + + + + + + + 健康检查 + + + + + + + + + + + +
+
+
+ 健康检查结果 +
+
+
耗时:--
+
+
+
+
+ + + + + + + + + + \ No newline at end of file