From 51db639606e44a1a3d72cc2e52832e0d4b95e1f4 Mon Sep 17 00:00:00 2001 From: maliming <6908465+maliming@users.noreply.github.com> Date: Fri, 18 Oct 2024 13:49:32 +0800 Subject: [PATCH] Add `EShopOnAbpHealthChecks`. --- .../EShopOnAbp.PublicWeb.csproj | 3 + .../EShopOnAbpPublicWebModule.cs | 7 +- .../HealthChecks/EShopOnAbpHealthCheck.cs | 32 ++++++++ .../HealthChecksBuilderExtensions.cs | 77 +++++++++++++++++++ 4 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 apps/public-web/src/EShopOnAbp.PublicWeb/HealthChecks/EShopOnAbpHealthCheck.cs create mode 100644 apps/public-web/src/EShopOnAbp.PublicWeb/HealthChecks/HealthChecksBuilderExtensions.cs diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj index 491dfb50..45c59bb3 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj @@ -11,6 +11,9 @@ + + + diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs index bafce43b..223ad3c2 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs @@ -25,6 +25,7 @@ using System.Net.Http.Headers; using System.Security.Claims; using EShopOnAbp.PublicWeb.Components.Toolbar.Footer; +using EShopOnAbp.PublicWeb.HealthChecks; using Microsoft.AspNetCore.Authentication.OAuth.Claims; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; @@ -110,7 +111,7 @@ public override void ConfigureServices(ServiceConfigurationContext context) { Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true; var configuration = context.Services.GetConfiguration(); - + context.Services.AddHttpForwarderWithServiceDiscovery(); ConfigureBasketHttpClient(context); @@ -278,6 +279,8 @@ await transformContext.HttpContext.GetTokenAsync("access_token") ); }); }); + + context.Services.AddEShopOnAbpHealthChecks(); } public override void OnApplicationInitialization(ApplicationInitializationContext context) @@ -383,4 +386,4 @@ private UserLoggedInEto CreateUserLoggedInEto(ClaimsPrincipal principal, HttpCon IsEmailVerified = isEmailVerified }; } -} \ No newline at end of file +} diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/HealthChecks/EShopOnAbpHealthCheck.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/HealthChecks/EShopOnAbpHealthCheck.cs new file mode 100644 index 00000000..083f73a4 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/HealthChecks/EShopOnAbpHealthCheck.cs @@ -0,0 +1,32 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Identity; + +namespace EShopOnAbp.PublicWeb.HealthChecks; + +public class EShopOnAbpHealthCheck : IHealthCheck, ITransientDependency +{ + protected readonly IIdentityUserAppService IdentityUserAppService; + + public EShopOnAbpHealthCheck(IIdentityUserAppService identityUserAppService) + { + IdentityUserAppService = identityUserAppService; + } + + public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) + { + try + { + await IdentityUserAppService.GetListAsync(new GetIdentityUsersInput { MaxResultCount = 1 }); + + return HealthCheckResult.Healthy($"Could connect to database and get record."); + } + catch (Exception e) + { + return HealthCheckResult.Unhealthy($"Error when trying to get database record. ", e); + } + } +} diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/HealthChecks/HealthChecksBuilderExtensions.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/HealthChecks/HealthChecksBuilderExtensions.cs new file mode 100644 index 00000000..c20e6b27 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/HealthChecks/HealthChecksBuilderExtensions.cs @@ -0,0 +1,77 @@ +using System; +using HealthChecks.UI.Client; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.DependencyInjection; + +namespace EShopOnAbp.PublicWeb.HealthChecks; + +public static class HealthChecksBuilderExtensions +{ + public static void AddEShopOnAbpHealthChecks(this IServiceCollection services) + { + // Add your health checks here + var healthChecksBuilder = services.AddHealthChecks(); + healthChecksBuilder.AddCheck("EShopOnAbp Health Check"); + + services.ConfigureHealthCheckEndpoint("/health-status"); + + // If you don't want to add HealthChecksUI, remove following configurations. + var configuration = services.GetConfiguration(); + var healthCheckUrl = configuration["App:HealthCheckUrl"]; + + if (string.IsNullOrEmpty(healthCheckUrl)) + { + healthCheckUrl = "/health-status"; + } + + var healthChecksUiBuilder = services.AddHealthChecksUI(settings => + { + settings.AddHealthCheckEndpoint("EShopOnAbp Health Status", healthCheckUrl); + }); + + // Set your HealthCheck UI Storage here + healthChecksUiBuilder.AddInMemoryStorage(); + + services.MapHealthChecksUiEndpoints(options => + { + options.UIPath = "/health-ui"; + options.ApiPath = "/health-api"; + }); + } + + private static IServiceCollection ConfigureHealthCheckEndpoint(this IServiceCollection services, string path) + { + services.Configure(options => + { + options.EndpointConfigureActions.Add(endpointContext => + { + endpointContext.Endpoints.MapHealthChecks( + new PathString(path.EnsureStartsWith('/')), + new HealthCheckOptions + { + Predicate = _ => true, + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse, + AllowCachingResponses = false, + }); + }); + }); + + return services; + } + + private static IServiceCollection MapHealthChecksUiEndpoints(this IServiceCollection services, Action? setupOption = null) + { + services.Configure(routerOptions => + { + routerOptions.EndpointConfigureActions.Add(endpointContext => + { + endpointContext.Endpoints.MapHealthChecksUI(setupOption); + }); + }); + + return services; + } +}