Implement Basic, Custom and Multiple Health Checks in .NET Web API

Introduction

In this article, we are going to learn about the basics of a Health Check endpoint and how to implement basic and custom health checks in .NET Web API.

What is a Health Check?

A health check is a mechanism used to monitor the status of services in a Web API. It provides an automated approach to confirm the status and state of an application and its dependencies, including databases, caches, and external services. The health check is accessible via an HTTP endpoint.

Why Do We Need a Health Check?

A health check is essential for consistently monitoring the status of an application and its dependencies. Imagine your application depends on a database. If the connection to this database is interrupted, the application is likely to encounter issues. By regularly using the Health Check endpoint, we can monitor the database connection and ensure the application runs without any issues.

ASP.NET Core provides three different Health Checks statuses,

  • Healthy: The application is in a healthy and functional state.
  • Unhealthy: The application is unhealthy, either offline or has thrown an unhandled exception during the check.
  • Degraded: The application is still running but not responding within the expected timeframe.

Types of Health Checks

  1. Basic health check
  2. System health check
  3. Database health check
  4. Custom health check

How to Implement Health Checks?

We can implement Health Checks by following these two steps.

  • Adding the Health Checks Library
  • Adding Health Check Services

Adding the Health Checks Library

First, we need to add the following NuGet package for the Health Checks middleware.

Microsoft.AspNetCore.Diagnostics.HealthChecks

Adding Health Check Services

To add health check services, follow these two steps in the Program.cs file:

  • Register Health Check Services
  • Configure Health Check Endpoints
var builder = WebApplication.CreateBuilder(args);

ConfigureServices(builder.Services);

var app = builder.Build();

Configure(app);

app.Run();


public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    
    // Register health checks
    services
        .AddHealthChecks().AddCheck("Health", ()=> HealthCheckResult.Healthy("Healthy"));
}

public void Configure(IApplicationBuilder app)
{
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        
        // Configure health checks
        endpoints.MapHealthChecks("/health");
    });
}

To check the health of your web API, navigate to https://localhost:5001/health. After calling this endpoint, you will see that your web API is marked as "Healthy".

Health checks

How to Implement Custom Health Checks

We can create our own Health Checks, which can execute custom code. IHealthCheck Interface is used to implement custom health checks. Let’s create a class called CustomHealthCheck and implement the IHealthCheck interface.

public class CustomHealthCheck: IHealthCheck
{
    public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
            
    }
}

Now, we will implement custom health check logic to assess the system's health as demonstrated below.

public class CustomHealthCheck: IHealthCheck
{
    public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        var randomNumber = new Random().Next(1, 100);
        
        if(randomNumber > 0 && randomNumber <= 50 )
        {
            return Task.FromResult(HealthCheckResult.Healthy("Healthy"));
        }
        else if(randomNumber > 50 && randomNumber <=75 )
        {
            return Task.FromResult(HealthCheckResult.Unhealthy("Unhealthy"));
        }
        
        return Task.FromResult(HealthCheckResult.Degraded("Degraded"));
    }
}

Register the above CustomHealthCheck service in Program.cs file

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    
    // Register custom health checks
    services
        .AddHealthChecks().AddCheck<CustomHealthCheck>("CustomHealthCheck");
}

public void Configure(IApplicationBuilder app)
{

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        
        endpoints.MapHealthChecks("/health");
    });
}

Now, if we navigate to https://localhost:5001/health, we will see the results of our custom health check.

Custom health checks

Adding Multiple Health Checks in Web API

It's also possible to have multiple health checks and filter them using tags.

In the example below, I have added tags to health check services, which are used to filter and retrieve the health status for specific services.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    
    services
        .AddHealthChecks().AddCheck("Health", ()=> HealthCheckResult.Healthy("Healthy"), tags: ["app_health"]);

    services
        .AddHealthChecks().AddCheck<CustomHealthCheck>("CustomHealthCheck", tags: new[] { "custom" });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        
        endpoints.MapHealthChecks("/health", new HealthCheckOptions
            {
                Predicate = healthCheck => healthCheck.Tags.Contains("app_health")
            });
        
        endpoints.MapHealthChecks("/health/custom", new HealthCheckOptions
            {
                Predicate = healthCheck => healthCheck.Tags.Contains("custom")
            });
    });
}

Run the services and test the below health check endpoints:

  • Service Health Check: https://localhost:5001/health
  • Custom Health Check: https://localhost:5001/health/custom

Health checks

Summary

In this article, you have learned the following topics,

  • What is a Health Check?
  • Why Do We Need a Health Check?
  • How to Implement Basic and Custom Health Checks
  • How to Implement Multiple Health Checks