ASP.NET Core 2.2.0-preview1: Healthchecks

What is it?

We’re adding a health checks service and middleware in 2.2.0 to make it easy to use ASP.NET Core in environments that require health checks – such as Kubernetes. The new features are set of libraries defining an IHealthCheck abstraction and service, as well as a middleware for use in ASP.NET Core.

Health checks are used by a container orchestrator or load balancer to quickly determine if a system is responding to requests normally. A container orchestrator might respond to a failing health check by halting a rolling deployment, or restarting a container. A load balancer might respond to a health check by routing traffic away from the failing instance of the service.

Typically health checks are exposed by an application as a simple HTTP endpoint used by monitoring systems. Creating a dedicated health endpoint allows you to specialize the behavior of that endpoint for the needs of monitoring systems.

How to use it?

Like many ASP.NET Core features, health checks comes with a set of services and a middleware.

public void ConfigureServices(IServiceCollection services)
{
...

    services.AddHealthChecks(); // Registers health checks services
}

public void Configure(IApplicationBuilder app)
{
...

    app.UseHealthChecks("/healthz");

...
}

 

This basic configuration will register the health checks services and and will create a middleware that responds to the URL path “/healthz” with a health response. By default no health checks are registered, so the app is always considered healthy if it is capable of responding to HTTP.

You can find a few more samples in the repo:

Understanding liveness and readiness probes

To understand how to make the most out out health checks, it’s important to understand the difference between a liveness probe and a readiness probe.

A failed liveness probe says: The application has crashed. You should shut it down and restart.

A failed readiness probe says: The application is OK but not yet ready to serve traffic.

The set of health checks you want for your application will depend on both what resources your application uses and what kind of monitoring systems you interface with. An application can use multiple health checks middleware to handle requests from different systems.

What health checks should I add?

For many applications the most basic configuration will be sufficient. For instance, if you are using a liveness probe-based system like Docker’s built in HEALTHCHECK directive, then this might be all you want.

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...

    services.AddHealthChecks(); // Registers health checks services
}

public void Configure(IApplicationBuilder app)
{
...

    app.UseHealthChecks("/healthz");

...
}

# Dockerfile
...

HEALTHCHECK CMD curl --fail http://localhost:5000/healthz || exit

 

If your application is running in Kubernetes, you may want to support a readiness probe that health checks your database. This will allow the orchestrator to know when a newly-created pod should start receiving traffic.

public void ConfigureServices(IServiceCollection services)
{
...
    services
        .AddHealthChecks()
        .AddCheck(new SqlConnectionHealthCheck("MyDatabase", Configuration["ConnectionStrings:DefaultConnection"]));
...
}

public void Configure(IApplicationBuilder app)
{
    app.UseHealthChecks("/healthz");
}

 

...
spec:
  template:
  spec:
    readinessProbe:
      # an http probe
      httpGet:
        path: /healthz
        port: 80
      # length of time to wait for a pod to initialize
      # after pod startup, before applying health checking
      initialDelaySeconds: 30
      timeoutSeconds: 1
    ports:
      - containerPort: 80

 

Customization

The health checks middleware supports customization along a few axes. All of these features can be accessed by passing in an instance of HealthCheckOptions.

  • Filter the set of health checks run
  • Customize the HTTP response
  • Customize the mappings of health status -> HTTP status codes

What is coming next?

In a future preview we plan to add official support for health checks based on an ADO.NET DbConnection or Entity Framework Core DbContext.

We expect that the way that IHealthCheck instances interact with Dependency Injection will be improved. The current implementation doesn’t provide good support for interacting with services of varying lifetimes.

We’re working with the authors of Polly to try and integrate health checks for Polly’s circuit breakers.

We plan to also provide guidance and examples for using the health check service with push-based health systems.

How can you help?

There are a few areas where you can provide useful feedback during this preview. We’re interested in any thoughts you have of course, these are a few specific things we’d like opinions on.

Is the IHealthCheck interface general and useful enough to be used broadly?

  • Including other health check systems
  • Including health checks written by other libraries and frameworks
  • Including health checks written by application authors

The best place to provide feedback is by logging issues on https://github.com/aspnet/Diagnostics

Caveats and notes

The health check middleware doesn’t disable caching for responses to the health endpoint. We plan to add this in the future, but it didn’t make it into the preview build.