In this series of posts, we will talk about health checks and monitor your web application/web API.
Also, check out my blog with other articles --> https://rmauro.dev
In this blog post, we'll add an endpoint to monitor your application health status.
And you'll see that it's pretty simple in .Net Core application. With just a few lines of code, we have the infrastructure ready to display the health status of our services.
We can monitor services such as:
- Database (SQL Server, Oracle, MySql, MongoDB and others)
- External API connectivity
- Disk connectivity (read/write)
- Cache service (Redis, Memcache, and others)
Basically anything you can think of. If you don't find an implementation that suits you, we can create our custom implementation.
Health Endpoint Monitoring pattern
But. Why?
Implement functional checks in an application that external tools can access through exposed endpoints at regular intervals. This can help to verify that applications and services are performing correctly.
Reference to: https://docs.microsoft.com/en-us/azure/architecture/patterns/health-endpoint-monitoring
Adding basic health check
First, add on ConfigureServices method the HealthCheck service.
public void ConfigureServices(IServiceCollection services)
{
//adding health check services to container
services.AddHealthChecks();
}
Startup.cs
Second, add on Configure pipeline the healthcheck endpoint.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//adding health check endpoint
app.UseHealthChecks("/healthcheck");
app.UseMvcWithDefaultRoute();
}
Startup.cs
for .Net Core 2.2
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/healthcheck");
endpoints.MapDefaultControllerRoute();
});
}
Startup.cs
for .Net Core 3.1
Always put before the UseMvc. We don't want to MVC pipeline executed before our endpoint.
Build, run, and access the URL http://{YOUR-URL}/healthcheck
you should see something like this.
All set and done to start adding services to the monitoring list. Now let's add one service to the monitor list - MongoDb.
Adding MongoDb as a monitor service
Let's pick from xabaril's list. xabaril's Github repository contains a bunch of AspNetCore.Diagnostics.HealthChecks packages ready for use.
- AspNetCore.HealthChecks.System
- AspNetCore.HealthChecks.Network
- AspNetCore.HealthChecks.SqlServer
- AspNetCore.HealthChecks.MongoDb
- AspNetCore.HealthChecks.Npgsql
- AspNetCore.HealthChecks.Elasticsearch
- AspNetCore.HealthChecks.Redis
- AspNetCore.HealthChecks.EventStore
- AspNetCore.HealthChecks.AzureStorage
- AspNetCore.HealthChecks.AzureServiceBus
- AspNetCore.HealthChecks.AzureKeyVault
- AspNetCore.HealthChecks.MySql
https://github.com/xabaril/AspNetCore.Diagnostics.HealthChecks
And many other packages.
Back to business.
First, add the Nuget package AspNetCore.HealthChecks.MongoDb
to your project.
And them modify the AddHealthChecks to include the MongoDB health check.
public void ConfigureServices(IServiceCollection services)
{
//adding health check services to container
services.AddHealthChecks()
.AddMongoDb(mongodbConnectionString: "YOUR-CONNECTION-STRING",
name: "mongo",
failureStatus: HealthStatus.Unhealthy); //adding MongoDb Health Check
}
Startup.cs
After these changes, it's all set up. You can execute your application and check again the health status page.
Adding another endpoint with more details
Now let's create another endpoint that will display more detailed information about our monitored endpoints.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//... ommited code
//adding health check endpoint
app.UseHealthChecks("/healthcheck");
//adding custom json response
app.UseHealthChecks("/hc",
new HealthCheckOptions
{
ResponseWriter = async (context, report) =>
{
var result = JsonConvert.SerializeObject(
new
{
status = report.Status.ToString(),
errors = report.Entries.Select(e => new { key = e.Key, value = Enum.GetName(typeof(HealthStatus), e.Value.Status) })
});
context.Response.ContentType = MediaTypeNames.Application.Json;
await context.Response.WriteAsync(result);
}
});
app.UseMvcWithDefaultRoute();
}
Startup.cs
for .Net 2.2
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//... ommited code
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/healthcheck");
endpoints.MapHealthChecks("/hc",
new HealthCheckOptions
{
ResponseWriter = async (context, report) =>
{ //using the new json serializer
var result = JsonSerializer.Serialize(
new
{
status = report.Status.ToString(),
errors = report.Entries.Select(e => new { key = e.Key, value = Enum.GetName(typeof(HealthStatus), e.Value.Status) })
});
context.Response.ContentType = MediaTypeNames.Application.Json;
await context.Response.WriteAsync(result);
}
});
endpoints.MapGet("/", async context => await context.Response.WriteAsync("Hello World!"));
endpoints.MapDefaultControllerRoute();
});
}
Startup.cs
for .Net 3.1
Run again and access the endpoints /hc
.
That is it!
In the next article, I'll show you how to put a good UI (user interface) to it.
Top comments (1)
Leave a comment if you like it!