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"
}
]
}
}
Top comments (0)