Camilo Garcia
Camilo Garcia

Reputation: 111

Health check, ASP.NET Web API

In my work I was asked to implement health checks into an ASP.NET Web API 2 written in C#. I have searched but all the documentation is for ASP.NET Core and its implementation, does anyone know how to implement health check features in the classic / full .NET Framework?

Upvotes: 10

Views: 11805

Answers (2)

techfooninja
techfooninja

Reputation: 195

I agree with Igor. Here's a concrete application of what he suggested (obviously, there are other ways to do this, but this is the best way I know how to keep it clear and honor separation of concerns):

  1. Create a new controller. In this example, I'll call it HealthController
  2. Add an action to the controller, and annotate it with [HttpGet]
  3. Place logic inside the action that checks for the stability of external dependencies. For example, if disk access is critical for your API, run a test or two to make sure that the disk is responding like you need it to. If you need to be able to query a database, make a sample query, and make sure it's successful. This part is completely custom and really depends on your API and how it needs to perform.
public class HealthController : ApiController
{
    [HttpGet]
    public IHttpActionResult Check()
    {
        // Add logic here to check dependencies
        if (/* successful */)
        {
            return Ok();
        }
        return InternalServerError(); // Or whatever other HTTP status code is appropriate
    }
}
  1. Have an external service issue a GET request to your endpoint (currently at https://whatever.your.domain.is/Health/Check) and report back when it doesn't receive 200 OK for some amount of time.

I've used Amazon CloudWatch in the past and I've been happy with it. There are going to be other services out there that will do this for you, but I don't have any experience with them.

Upvotes: 8

Andrew Cooper
Andrew Cooper

Reputation: 32576

The Microsoft.Extensions.Diagnostic.HealthChecks packages are compatible with .Net Framework and can be used as per the existing documentation. The missing piece is just a handler to handle requests to the endpoint and run the health checks.

I've recently implemented health checks in an application targeting net472 as follows:

  • Create implementations of IHealthCheck as documented for an ASP.Net Core application.
  • Add a handler for the health endpoint. In my case I created a terminal OwinMiddleware:
    public class HealthCheckHandler : OwinMiddleware
    {
        private readonly HealthCheckService _healthCheckService;
    
        public HealthCheckHandler(OwinMiddleware next, HealthCheckService healthCheckService)
            : base(next)
        {
            _healthCheckService = healthCheckService;
        }
    
        public override async Task Invoke(IOwinContext context)
        {
            var report = await _healthCheckService.CheckHealthAsync(context.Request.CallCancelled); 
    
            if (report.Status == HealthStatus.Unhealthy)
            {
                context.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
            }
    
            context.Response.ContentType = "application/json";
            await context.Response.WriteAsync(report.ToJsonString());
        }
    }
    
  • Add the health checks to your DI Container per the existing documentation. In my case I configured Autofac by:
    var services = new ServiceCollection();
    services.AddHealthChecks().AddCheck<MyHealthCheck>(MyCheck);
    
    builder.Populate(services);
    
    That last method is in the Autofac.Extensions.DependencyInjection package.
  • In the application startup, resolve an instance of Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckService from the DI container and then call :
    app.Map("/health", x => x.Use(typeof(HealthCheckHandler), healthCheckService));
    

Upvotes: 1

Related Questions