How to implement health checks in ASP.Net Core

Take advantage of health check middleware in ASP.Net Core to monitor the health of your application, its database connection, and more

Health checks are used to determine if the application is responding to requests normally. ASP.Net Core provides support for health checks for reporting the health of an application using health check middleware, which was introduced in ASP.Net Core 2.2.

Health checks in ASP.Net Core are exposed as HTTP endpoints and are configurable. You can use health checks to do a basic check for liveness, to check system or network resources, to check whether the database is responding, or to check on other dependencies such as a message broker or an Azure cloud service. This article presents a discussion of how we can work with the health check middleware in ASP.Net Core.

Create an ASP.Net Core project in Visual Studio

First off, let’s create an ASP.Net Core project. If Visual Studio 2017 is up and running in your system, follow the steps given below to create a new ASP.Net Core project in Visual Studio.

  1. Launch the Visual Studio 2017 IDE.
  2. Click on File > New > Project.
  3. Select “ASP.Net Core Web Application (.Net Core)” from the list of the templates displayed.
  4. Specify a name for the project.
  5. Click OK to save the project.
  6. A new window “New .Net Core Web Application…” is shown next.
  7. Select .Net Core as the runtime and ASP.Net Core 2.2 (or later) from the drop-down list at the top.
  8. Select API as the project template.
  9. Ensure that the check boxes “Enable Docker Support” and “Configure for HTTPS” are unchecked as we won’t be using those features here.
  10. Ensure that “No Authentication” is selected as we won’t be using authentication either.
  11. Click OK.

This will create a new ASP.Net Core project in Visual Studio. We’ll use this project in the subsequent sections of this article.

Register health check services in ASP.Net Core

To register health check services, you should call the AddHealthChecks method in the ConfigureServices method of the Startup class. Next, you should add the health check middleware by calling the UseHealthChecks as shown in the code snippet below.

       public void ConfigureServices(IServiceCollection services)
        {
            services.AddHealthChecks();
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseHealthChecks("/health");
            app.UseStaticFiles();
            app.UseCookiePolicy();
            app.UseMvc();
        }

Note that both the ConfigureServices and Configure methods are called by the runtime.

Built-in health checks in ASP.Net Core

You can take advantage of the built-in Entity Framework Core DbContext health check to report if the Entity Framework Core DbContext is able to connect to the database. To do this, you should add the Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore NuGet package and configure health checks in the ConfigureServices method as shown below.

services.AddHealthChecks().AddDbContextCheck<MyDbContext>
("IDGDbContextHealthCheck");

You can also leverage other health check packages available in NuGet if need be. These include SQL Server, MySQL, MongoDB, Redis, RabbitMQ, Elasticsearch, Hangfire, Kafka, Oracle, Azure Storage, and more. These community packages are available in the AspNetCore.Diagnostics.HealthChecks repository on GitHub

Create custom health checks in ASP.Net Core

You can build custom health checks to verify and report if the application is unable to connect to the database or an external service, for example. To create a custom health check, you should extend the IHealthCheck interface and implement the CheckHealthAsync method.

    public class MyCustomHealthCheck : IHealthCheck
    {
        public Task<HealthCheckResult>
        CheckHealthAsync(HealthCheckContext context,
        CancellationToken cancellationToken =
        default(CancellationToken))
        {
            throw new System.NotImplementedException();
        }
    }

Here’s how you can implement the CheckHealthAsync method. Note how the HealthCheckResult struct has been used in this method.

        public async Task<HealthCheckResult>
         CheckHealthAsync(HealthCheckContext context,
         CancellationToken cancellationToken =
         default(CancellationToken))
        {
            bool canConnect = IsDBOnline();
            if (canConnect)
                return HealthCheckResult.Healthy();
            return HealthCheckResult.Unhealthy();
        }

The IsDBOnline method checks if the database is up and running.

private bool IsDBOnline()
        {
            string connectionString =
            "some connection string to connect to the database";
           try
           {
              using (SqlConnection connection = new
              SqlConnection(connectionString))
              {
                    if (connection.State !=
                       System.Data.ConnectionState.Open)
                     connection.Open();
              }
               return true;
           }
           catch (System.Exception)
           {
               return false;
           }
        }

Here is the complete code listing for your reference.

using Microsoft.Extensions.Diagnostics.HealthChecks;
using System.Threading;
using System.Threading.Tasks;
namespace IDGHealthCheckApp
{
    public class MyCustomHealthCheck : IHealthCheck
    {
        public async Task<HealthCheckResult>
         CheckHealthAsync(HealthCheckContext context,
         CancellationToken cancellationToken =
         default(CancellationToken))
        {
            bool canConnect = IsDBOnline();
            if (canConnect)
                return HealthCheckResult.Healthy();
            return HealthCheckResult.Unhealthy();
        }
private bool IsDBOnline()
        {
            string connectionString =
            "some connection string to connect to the database";
           try
           {
              using (SqlConnection connection = new
              SqlConnection(connectionString))
              {
                    if (connection.State !=
                       System.Data.ConnectionState.Open)
                     connection.Open();
              }
               return true;
           }
           catch (System.Exception)
           {
               return false;
           }
        }
    }
}

The HealthCheckResult object shown in the code snippet above enables us to pass description, exception, and status data represented as a dictionary of key-value pairs. This information can then be presented in the health check web page. Once your custom health check is built, you should configure the custom health check type appropriately in the ConfigureServices and Configure methods of the Startup class to start leveraging it.

Visualizing health checks in ASP.Net Core

If you would like to visualize the health check in a better way, you can take advantage of an open source visualization tool named HealthChecksUI. To use this tool, install it from NuGet by using the following command at the package manager console window.

Install-Package AspNetCore.HealthChecks.UI

Once the package has been installed, you should configure it in the ConfigureServices and Configure methods of the Startup class.

public void ConfigureServices(IServiceCollection services)
{
    services.AddHealthChecksUI();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHealthChecks("/health", new HealthCheckOptions
{
    Predicate = _ => true,
    ResponseWriter =
    UIResponseWriter.WriteHealthCheckUIResponse
});
    app.UseHealthChecksUI();
}

That’s not all. You should also add the following configuration in the appsettings.json file to let HealthChecksUI know where to fetch the health check information.

  "HealthChecks-UI": {
    "HealthChecks": [
      {
        "Name": "Local",
        "Uri": "http://localhost:1994/health"
      }
    ],
    "EvaluationTimeOnSeconds": 10,
    "MinimumSecondsBetweenFailureNotifications": 60
  }

Finally, start your application and navigate to /healthchecks-ui to monitor its health. 

aspnet core healthchecksui IDG

HealthChecksUI in action.

The health check middleware in ASP.Net Core makes it is easy to add and configure health checks of system resources, databases, and other services your application depends on. It is up to you to determine what is considered healthy and what is considered unhealthy, and to configure how the health check endpoint should respond. You can even send out failure notifications when a health check fails—such as when your application is unable to connect to the database.

Copyright © 2019 IDG Communications, Inc.