DEV Community

Ben Witt
Ben Witt

Posted on • Originally published at Medium

HealthChecks

From time to time it happens that the connection to the database fails or the services or containers crash. This can lead to a considerable investigation effort to find the reasons why these problems occur, which can be facilitated by the use of “HealthChecks”.

ASP.NET provides a convenient and effective approach to implementing this functionality.

To achieve this, the following nuggets need to be installed:

Image description

To include the following items in the Program.cs file:

builder.Services.AddHealthChecks();  
...  
...  
//Now the HealthChecks should be mapped to the current endpoint  
app.MapHealthChecks("/_health");
Enter fullscreen mode Exit fullscreen mode

This would provide us with the foundation to check the health of our application. Currently, no checks are performed, so our application is considered to be in a healthy state.

Upon launching the app, initially, only the Swagger site is loaded and no other content is visible. Let’s simply update the address to:

Image description
To extend our HealthCheck with a custom check, we will create a new class called “MyFirstHealthCheck” with the following content:

public class MyFirstHealthCheck : IHealthCheck  
{    
  public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)    
  {      
    return Task.FromResult(HealthCheckResult.Healthy("This could be a service"));    
  }  
}
Enter fullscreen mode Exit fullscreen mode

This class serves the purpose of returning a “HealthCheckResult” with the status “Healthy”.

We have reached a point where we need to include this check in our Program.cs file. When we call this check, the situation looks a little different. Initially, the appearance remains unchanged. However, if we set a breakpoint in the source code, it will be triggered when we refresh the page.

Image description
Instead of using the term “healthy”, which is not very meaningful, it would be more helpful to convey a specific message. For example, we could use a more descriptive message to communicate the status or result of the test.

To accomplish this, we need to ensure that the NuGet package “AspNetCore.HealthChecks.UI.Client” is installed. After that, we can proceed to extend the following functionality:

In the Program.cs file, we need to incorporate a ResponseWriter into the mapper of the HealthCheck. This will enable us to customize the output or response generated by the HealthCheck module.

Image description
Let’s restart the program and see what comes out of it.

Image description

To enable easy retrieval from a list, we can assign a tag to this check. Implementing the tag in the service would facilitate the process.

Image description
Now let’s execute this request once more.

Image description
Let’s create another check:

Image description
It can be a bit overwhelming at first.

To create a dashboard that lists all our checks using the NuGet package “AspNetCore.HealthChecks.UI.Client," we need to make three additions to the Program.cs file:

1. Add a new service:

This new dashboard requires persistent storage, so we need to add the NuGet package “AspNetCore.HealthChecks.UI.InMemory.Storage."

Image description

2. New Mapping

Below the previous AddHealthChecks() method call, we can add a new method call AddHealthChecksUI() that uses the in-memory store.

To map this new user interface, we can add a route to the Configure() method in the Startup.cs file. The route should point to the Health Checks UI endpoint.

Image description

3.) AppSettings.json

To configure the dashboard to forward requests to the appropriate address, you can modify the appsettings.json file. Within the file, you will need to update the relevant settings to specify the desired address for request forwarding.

Image description
We start the application and change the address:

Image description
Now our dashboard opens:

Image description
By utilizing the dashboard we have created, we can now have a comprehensive overview of the checks we have implemented for our application. The dashboard not only displays the current status of the checks but also provides a history section that gives us insights into the events that have occurred from the application’s start until now. To access more detailed information, we can explore the details section within the dashboard.

Image description
What could a HealthCheck that monitors the connection to the database look like?

We create a new object that checks the connection to the database.

public class DatabaseConnectionCheck : IHealthCheck
{
  public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
  {
    try
    {
      using var connection = new SqlConnection("Data Source=.;Initial Catalog=MyDatabase;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False");
      await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
      using var command = connection.CreateCommand();
      command.CommandText = "Select 1";
      object result = await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false);

      return HealthCheckResult.Healthy("The status of the connection is open");
    }
    catch (Exception ex)
    {
      return HealthCheckResult.Unhealthy("The status of the connection is close");
    }

  }
}
Enter fullscreen mode Exit fullscreen mode

Here only the connection to the database is established and by the select 1 it is checked whether the query can be sent or not. Accordingly, a result is returned which is healthy or unhealthy.

Now we only have to announce the service:

Image description
Now we have a comprehensive overview of all the checks that have been configured in our application. This provides a clear and organized display of the various checks and their respective statuses, making it easier to monitor and track the health of our application.

Image description
these checks are queried every 5 seconds as we set, now if the connection to the database is closed or interrupted, this dashboard will react to it:

Image description
you will find a number of nuget dealing with some topics:

Image description
Github: HealthChecks

Top comments (0)