Application Health Check Using ASP.NET Core

Agenda

 
In this article we will learn about application health check middleware that .net core provides and understand various checks we can perform using this middleware.
 
Prerequisite
  • Knowledge on .net core middleware’s
Application health has become the core of any business. An application which is not stable (unhealthy) leads to lots of revenue loss, customer trust and negative impacts on business. To avoid such cases, we should regularly monitor the status of our applications.
 
Application health checks are when you define “healthy” parameters for the monitoring metrics across your application and run regular checks to ensure the system is performing the way it’s expected to.
 
Using these health checks, we can be notified of outages before customers and reduce the impact of outage by fixing them or informing the customer about the ongoing outage with time to up which leads to gaining the trust.
 
Monitoring depends on complexity and criticality of the application. A simple application may require monitoring its dependencies once a day, whereas a critical application may be required to be monitored as frequently as possible. We can also provide a status page to see the results and add functionality to notify developers about problems.
 
Let’s see how we can do these health checks using asp.net core,
 
Every dotnet core application implicitly refers a package Microsoft.AspNetCore.Diagnostics.HealthChecks package which makes it easy to add a basic health check to our application
 
Application Health Check Using ASP.NET Core
 
So, to enable health check endpoint we need to do below two code changes (highlighted in yellow) to our startup.cs file
 
Application Health Check Using ASP.NET Core
 
Apart from these two lines we are not doing anything but when we try to call the health route endpoint it returns the status of my application.
 
Application Health Check Using ASP.NET Core
There are three types of health status that are returned back to the monitoring service which uses the health check.
  • Degraded - Indicates that the component was in a degraded state.
  • Healthy - Indicates that the component was healthy.
  • Unhealthy - Indicates that the component was unhealthy, or an unhandled exception was thrown while executing the health check.
In the real world this basic health check won't be enough to know the status of the app, we need to monitor the health of dependencies of the application like a database or other external API or storage account which is used in our application.
 
There are many NuGet packages available for commonly used services, i am listing a few packages below which are popularly used
 
Application Health Check Using ASP.NET Core
 
We have to add the NuGet package and code in startup.cs file to do a basic health check for these services.
 
For SQL Server health check
 
Install AspNetCore.HealthChecks.SqlServer package and add below highlighted code.
 
Application Health Check Using ASP.NET Core
 
This will check our SQL DB health before returning the result to the health route endpoint which we added earlier.
 
For Azure Storage health check
 
Install AspNetCore.HealthChecks.AzureStorage and add below highlighted code:
 
Application Health Check Using ASP.NET Core
 
For URI health check
 
Install AspNetCore.HealthChecks.Uris and add below highlighted code,
 
Application Health Check Using ASP.NET Core
 
There are many such packages which we can install and so changes to our startup file which will do a health check for us.
 
Health check Predicate Options
 
We can also add tags to these health checks and add route filtering to execute health checks as shown below,
 
In the below example I have added tags to health check profiles, so i can filter and get health status only for specific sets as per my requirement.
 
Application Health Check Using ASP.NET Core
 
Changed endpoints as below,
 
Application Health Check Using ASP.NET Core
 
In this way we can configure health check for our application and link to any external UI monitoring (for example: https://uptimerobot.com/) or add AspNetCore.HealthChecks.UI NuGet package to your web project create UI for monitoring.
 
Health checks are usually used with an external monitoring service or container orchestrator to check the status of an app. Before adding health checks to an app, decide on which monitoring system to use. The monitoring system dictates what types of health checks to create and how to configure their endpoints.
 
Code snippet for startup.cs
  1. using Microsoft.AspNetCore.Builder;  
  2. using Microsoft.AspNetCore.Diagnostics.HealthChecks;  
  3. using Microsoft.AspNetCore.Hosting;  
  4. using Microsoft.Extensions.Configuration;  
  5. using Microsoft.Extensions.DependencyInjection;  
  6. using Microsoft.Extensions.Hosting;  
  7. using System;  
  8. namespace Healthchecks {  
  9.     public class Startup {  
  10.         public Startup(IConfiguration configuration) {  
  11.             Configuration = configuration;  
  12.         }  
  13.         public IConfiguration Configuration {  
  14.             get;  
  15.         }  
  16.         // This method gets called by the runtime. Use this method to add services to the container.  
  17.         public void ConfigureServices(IServiceCollection services) {  
  18.             services.AddControllers();  
  19.             services.AddHealthChecks().AddSqlServer(Configuration["ConnectionStrings:dbConnectionString"], tags: new [] {  
  20.                 "db",  
  21.                 "all"  
  22.             }).AddAzureBlobStorage(Configuration["ConnectionStrings:blobConnectionString"], tags: new [] {  
  23.                 "AzureStorage",  
  24.                 "all"  
  25.             }).AddAzureQueueStorage(Configuration["ConnectionStrings:QueueConnectionString"], tags: new [] {  
  26.                 "AzureStorage",  
  27.                 "all"  
  28.             }).AddUrlGroup(new Uri("https://testdemo.azurewebsites.net/health"), tags: new [] {  
  29.                 "testdemoUrl",  
  30.                 "all"  
  31.             });  
  32.             services.AddSwaggerGen();  
  33.         }  
  34.         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.  
  35.         public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {  
  36.             if (env.IsDevelopment()) {  
  37.                 app.UseDeveloperExceptionPage();  
  38.             }  
  39.             app.UseHttpsRedirection();  
  40.             app.UseSwagger();  
  41.             app.UseSwaggerUI(s => {  
  42.                 s.SwaggerEndpoint("/swagger/v1/swagger.json""My API V1");  
  43.             });  
  44.             app.UseRouting();  
  45.             app.UseAuthorization();  
  46.             app.UseEndpoints(endpoints => {  
  47.                 endpoints.MapControllers();  
  48.                 endpoints.MapHealthChecks("/health"new HealthCheckOptions() {  
  49.                     Predicate = (check) => check.Tags.Contains("all")  
  50.                 });  
  51.                 endpoints.MapHealthChecks("/health/AzureStorage"new HealthCheckOptions() {  
  52.                     Predicate = (check) => check.Tags.Contains("AzureStorage")  
  53.                 });  
  54.             });  
  55.         }  
  56.     }  
  57. }  
I hope you liked this article. In case you found the article  useful then kindly like and share it.