DEV Community

Ricardo
Ricardo

Posted on • Updated on • Originally published at rmauro.dev

Adding Health Checks to .Net Core Application

In this series of posts, we will talk about health checks and monitor your web application/web API.

Also, check out my blog with other articles --> https://rmauro.dev

In this blog post, we'll add an endpoint to monitor your application health status.

And you'll see that it's pretty simple in .Net Core application. With just a few lines of code, we have the infrastructure ready to display the health status of our services.

We can monitor services such as:

  • Database (SQL Server, Oracle, MySql, MongoDB and others)
  • External API connectivity
  • Disk connectivity (read/write)
  • Cache service (Redis, Memcache, and others)

Basically anything you can think of. If you don't find an implementation that suits you, we can create our custom implementation.

Health Endpoint Monitoring pattern

But. Why?

Implement functional checks in an application that external tools can access through exposed endpoints at regular intervals. This can help to verify that applications and services are performing correctly.

Reference to: https://docs.microsoft.com/en-us/azure/architecture/patterns/health-endpoint-monitoring

Adding basic health check

First, add on ConfigureServices method the HealthCheck service.

public void ConfigureServices(IServiceCollection services)
{
    //adding health check services to container
    services.AddHealthChecks();
}
Enter fullscreen mode Exit fullscreen mode

Startup.cs

Second, add on Configure pipeline the healthcheck endpoint.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    //adding health check endpoint
    app.UseHealthChecks("/healthcheck");

    app.UseMvcWithDefaultRoute();
}
Enter fullscreen mode Exit fullscreen mode

Startup.cs for .Net Core 2.2

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/healthcheck");
        endpoints.MapDefaultControllerRoute();
    });
}
Enter fullscreen mode Exit fullscreen mode

Startup.cs for .Net Core 3.1

Always put before the UseMvc. We don't want to MVC pipeline executed before our endpoint.

Build, run, and access the URL http://{YOUR-URL}/healthcheck you should see something like this.

basic-health-check

All set and done to start adding services to the monitoring list. Now let's add one service to the monitor list - MongoDb.

Adding MongoDb as a monitor service

Let's pick from xabaril's list. xabaril's Github repository contains a bunch of AspNetCore.Diagnostics.HealthChecks packages ready for use.

  • AspNetCore.HealthChecks.System
  • AspNetCore.HealthChecks.Network
  • AspNetCore.HealthChecks.SqlServer
  • AspNetCore.HealthChecks.MongoDb
  • AspNetCore.HealthChecks.Npgsql
  • AspNetCore.HealthChecks.Elasticsearch
  • AspNetCore.HealthChecks.Redis
  • AspNetCore.HealthChecks.EventStore
  • AspNetCore.HealthChecks.AzureStorage
  • AspNetCore.HealthChecks.AzureServiceBus
  • AspNetCore.HealthChecks.AzureKeyVault
  • AspNetCore.HealthChecks.MySql

https://github.com/xabaril/AspNetCore.Diagnostics.HealthChecks

And many other packages.

Back to business.

First, add the Nuget package AspNetCore.HealthChecks.MongoDb to your project.

And them modify the AddHealthChecks to include the MongoDB health check.

public void ConfigureServices(IServiceCollection services)
{
    //adding health check services to container
    services.AddHealthChecks()
        .AddMongoDb(mongodbConnectionString: "YOUR-CONNECTION-STRING",
        name: "mongo", 
        failureStatus: HealthStatus.Unhealthy); //adding MongoDb Health Check
}
Enter fullscreen mode Exit fullscreen mode

Startup.cs

After these changes, it's all set up. You can execute your application and check again the health status page.

basic-health-check

Adding another endpoint with more details

Now let's create another endpoint that will display more detailed information about our monitored endpoints.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //... ommited code

    //adding health check endpoint
    app.UseHealthChecks("/healthcheck");

    //adding custom json response
    app.UseHealthChecks("/hc",
       new HealthCheckOptions
       {
           ResponseWriter = async (context, report) =>
           {
               var result = JsonConvert.SerializeObject(
                   new
                   {
                       status = report.Status.ToString(),
                       errors = report.Entries.Select(e => new { key = e.Key, value = Enum.GetName(typeof(HealthStatus), e.Value.Status) })
                   });
               context.Response.ContentType = MediaTypeNames.Application.Json;
               await context.Response.WriteAsync(result);
           }
       });

    app.UseMvcWithDefaultRoute();
}
Enter fullscreen mode Exit fullscreen mode

Startup.cs for .Net 2.2

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //... ommited code

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/healthcheck");
        endpoints.MapHealthChecks("/hc",
           new HealthCheckOptions
           {
               ResponseWriter = async (context, report) =>
               {   //using the new json serializer
                   var result = JsonSerializer.Serialize(
                       new
                       {
                           status = report.Status.ToString(),
                           errors = report.Entries.Select(e => new { key = e.Key, value = Enum.GetName(typeof(HealthStatus), e.Value.Status) })
                       });

                   context.Response.ContentType = MediaTypeNames.Application.Json;

                   await context.Response.WriteAsync(result);
               }
           });

        endpoints.MapGet("/", async context => await context.Response.WriteAsync("Hello World!"));
        endpoints.MapDefaultControllerRoute();
    });
}
Enter fullscreen mode Exit fullscreen mode

Startup.cs for .Net 3.1

Run again and access the endpoints /hc.

custom-health-check

That is it!

In the next article, I'll show you how to put a good UI (user interface) to it.

Source Code At - branch Article-1

Originally posted at

Reference Articles

Discussion (1)

Collapse
rmaurodev profile image
Ricardo Author

Leave a comment if you like it!