ASP.NET Core 2.2 & 3 REST API #27 — Health Checks
By: Theodoros Ntakouris
Tags: Software Engineering, Microsoft, Csharp, Aspnetcore, Rest Api

A healthcheck is just a way to ensure our application (as a whole), or specific components work as expected. All of this information is going to be accessible through a health endpoint.

Apart from monitoring reasons, if let’s say, we had a scaled-out system that is positioned behind a traffic manager, we want our traffic manager/load balancer to know which of these services are health so it can redirect traffic to them, in order to achieve 0 downtime.

Let’s just create a new HealthCheckInstaller , in order to add services.AddHealthChecks() and also, on our Startup.cs/Configure method, add app.UseHealthChecks("/health") and that’s it.

If we just hit this health endpoint now, we just get a Health text message.

This does not actually do much, it just checks wether the API is up and running, like a test endpoint. What we need to integrate with this system is our SQL Server and our Redis cache.

We’re going to see 2 things:

How to use a pre-existing package to automatically inject configuration for the SQL Server database context

How to create our custom health checking component to integrate this with the Redis cache (there are packages that already do that, but this is a demonstration on what the framework allows us to do)

SQL Server

Add the Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore package through the NuGet interface.

ASP.NET Core has got lots of packages for different libraries you can use and you can typically find them under the Microsoft.Extensions.Diagnostics.HealthChecks namespace

You can now update the services.AddHealthChecks().AddDbContextCheck<DataContext>() . By simply doing that, the health checks are installed for the SQL Server, but there is one more thing needed in order to change the plain health message that the endpoint returns.

Let’s see how to customise this:

Create a HealthChecks directory under the contracts projects (not versioned)

directory under the contracts projects (not versioned) Under this, create a new HealthCheckResponse :

And a HealthCheck class as well :

The part where you plug these contracts in the framework is an overload of the .UseHealthChecks method. It has an extra HealthCheckOptions parameter, which contains a ResponseWriter , which is basically an async function that takes in the HttpContext and the other health check reports, composing the final response.

That’s the basic stuff set in place.

Redis

This is the custom part that .NET makes so easy to implement. Start by creating a HealthChecks/RedisHealthCheck : IHealthCheck . Override the missing methods and we are ready to write some code in order to return Health-Degrated-Unhealthy status, along with possible reasons.

The first thing we need is to add the ConnectionMultiplexer as a singleton, inside our Redis installer.

services.AddSingleton<IConnectionMultiplexer>(_ => ConnectionMultiplexer.Connect(redisCacheSettings.ConnectionString));

In the actual health check, we can inject that through the constructor.

There are many approaches to manual health checks, we are going to take the simplest (and effective) way.

Try to make a call to Redis

If you get a response without an error, return healthy

Else, something is wrong and you need to bubble up the error message to the health check endpoint response

Please do not pass the whole exception message to your production servers, without making sure that there are not sensitive information exposed first.