In this post we will integrate ASP.NET Core Health-Checks in .NET 5 Core API Project. This is a straightforward, quick start guide to get things started with health checks with a graphical user interface and no database dependency.
In this example a memory check based on the Garbage collector will be setup. We will use the AspNetCore.Diagnostics.HealthChecks library to display the results in a more friendly User interface.
Setup
The first step is to create a new ASP.NET Core WebApi project in your environment. In this example I will use openApi set as true and .NET 5.
Packages
Install the following nuget packages:
- AspNetCore.HealthChecks.UI
- AspNetCore.HealthChecks.UI.InMemory.Storage
- AspNetCore.HealthChecks.UI.Client
ConfigureServices
public void ConfigureServices(IServiceCollection services) { services.AddHealthChecks().AddCheck<MemoryHealthCheck>("Memory"); services.AddHealthChecksUI(opt => { opt.SetEvaluationTimeInSeconds(15); //time in seconds between check }).AddInMemoryStorage(); services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApi.HealthCheck", Version = "v1" }); }); }
Configure
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseSwagger(); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApi.HealthCheck v1")); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); app.UseRouting() .UseEndpoints(config => { config.MapHealthChecks("/hc", new HealthCheckOptions { Predicate = _ => true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse }); config.MapHealthChecksUI(setup => { setup.UIPath = "/hc-ui"; setup.ApiPath = "/hc-json"; }); config.MapDefaultControllerRoute(); }); }
MemoryCheck.cs
public class MemoryHealthCheck : IHealthCheck { private readonly IOptionsMonitor<MemoryCheckOptions> _options; public MemoryHealthCheck(IOptionsMonitor<MemoryCheckOptions> options) { _options = options; } public string Name => "memory_check"; public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { var options = _options.Get(context.Registration.Name); // Include GC information in the reported diagnostics. var allocated = GC.GetTotalMemory(forceFullCollection: false); var data = new Dictionary<string, object>() { { "AllocatedBytes", allocated }, { "Gen0Collections", GC.CollectionCount(0) }, { "Gen1Collections", GC.CollectionCount(1) }, { "Gen2Collections", GC.CollectionCount(2) }, }; var status = (allocated < options.Threshold) ? HealthStatus.Healthy : context.Registration.FailureStatus; return Task.FromResult(new HealthCheckResult( status, description: "Reports degraded status if allocated bytes " + $">= {options.Threshold} bytes.", exception: null, data: data)); } } public class MemoryCheckOptions { // Failure threshold (in bytes) public long Threshold { get; set; } = 1024L * 1024L * 1024L; }
appsettings.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "HealthChecksUI": { "HealthChecks": [ { "Name": "Web App", "Uri": "/hc" } ] } }

