loading...

Adding Health Checks to .Net Core Application

rmaurodev profile image Ricardo Updated on ・3 min read

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();
}

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();
}

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();
            });
        }

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
}

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();
}

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();
            });
        }

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

Posted on by:

rmaurodev profile

Ricardo

@rmaurodev

Software Architect | Cloud Expert | MCT

Discussion

pic
Editor guide
 

Leave a comment if you like it!