How to

Not just a ‘one-trick’ pony: How to use .net Core to Monitor App Health

Software development companies in Sri Lanka

Monitoring app health is of utmost importance in order to ensure that bugs and other vulnerabilities are patched on time. Today, let’s delve into ASP.net Core, a middleware solution that provides support to conduct health checks on an application.

First introduced in ASP.net Core 2.2, the health check feature is exposed via configurable HTTP endpoints. These health checks can then be used to check whether a database is responding, to check whether all dependencies are in order and more.

Getting started To get started, create an ASP.net Core project in Visual Studio 2017. To do so,

  1. Launch the Visual Studio 2017 IDE.
  2. Click on File > New > Project.
  3. Select “ASP.Net Core Web Application (.Net Core)” from the list of the templates displayed.
  4. Specify a name for the project.
  5. Click OK to save the project.
  6. A new window “New .Net Core Web Application…” is shown next.
  7. Select .Net Core as the runtime and ASP.Net Core 2.2 (or later) from the drop-down list at the top.
  8. Select API as the project template.
  9. Ensure that the checkboxes “Enable Docker Support” and “Configure for HTTPS” are unchecked
  10. Ensure that “No Authentication” is selected as it is not necessary.
  11. Click OK.

Register health check services

Next, proceed to call the AddHealthChecks method in the ConfigureServices method of the Startup class. The health check middleware can be added by calling the UseHealthChecks as shown in the code snippet below.

public void ConfigureServices(IServiceCollection services)
 {
    services.AddHealthChecks();
 }
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
 {
   app.UseHealthChecks("/health");
   app.UseStaticFiles();
   app.UseCookiePolicy();
   app.UseMvc();
 }

Do note that under this method, both the ConfigureServices and Configure methods are called by the runtime.

Built-in vs. custom health checks

Now we come to a fork in the road. ASP.net provides us the ability to either use the built-in health check or to deploy custom health checks.

The built-in health check allows you to take advantage of the Entity Framework Core DbContext health check to report if the Entity Framework Core DbContext is able to connect to a given database. To do this, add the Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore NuGet packages and configures health checks in the ConfigureServices method as shown below.

services.AddHealthChecks().AddDbContextCheck<MyDbContext>
("IDGDbContextHealthCheck");

Do remember that you always have the option of using other health check packages available on NuGet. These include SQL Server, MySQL, MongoDB, Redis, RabbitMQ, Elasticsearch, Hangfire, Kafka, Oracle, Azure Storage, and more. These community packages are available in the AspNetCore.Diagnostics.HealthChecks repository on GitHub.

This doesn’t work for me. I want to go custom.

Assume you want to verify if the application is unable to connect to a database or an external service. If you decide to create a custom health check, extend the IHealthCheck interface and implement the CheckHealthAsync method.

public class MyCustomHealthCheck : IHealthCheck
	{
        public Task<HealthCheckResult>
    	CheckHealthAsync(HealthCheckContext context,
    	CancellationToken cancellationToken =
    	default(CancellationToken))
    	{
        	throw new System.NotImplementedException();
    	}
	}

Note how the HealthCheckResult struct has been used here.

public async Task<HealthCheckResult>
     	CheckHealthAsync(HealthCheckContext context,
     	CancellationToken cancellationToken =
     	default(CancellationToken))
    	{
		if (IsDBOnline())
{
            		return HealthCheckResult.Healthy();
}
        	return HealthCheckResult.Unhealthy();
    	}

The IsDBOnline method can be used to check if the database is working as intended.

private bool IsDBOnline()
    	{
        	string connectionString =
        	"some connection string to connect to the database";
       	try
       	{
          	using (SqlConnection connection = new
          	SqlConnection(connectionString))
          	{
                	if (connection.State !=
                   	System.Data.ConnectionState.Open)
                 	connection.Open();
          	}
           	return true;
       	}
       	catch (System.Exception)
       	{
           	return false;
       	}
    	}

The HealthCheckResult object shown in the code above allows us to pass description, exception, and status data represented as a dictionary of key-value pairs. This information can then be presented on a health check web page. After building your custom health check, remember to configure the custom health check type appropriately in the ConfigureServices and Configure methods of the Startup class to start leveraging it.

Visualize your health check

If you wish to view the results of your health check in a more visually appealing format, you can use an open-source visualization tool named HealthChecksUI. To use this tool, install it from NuGet by using the following command at the package manager console window.

Install-Package AspNetCore.HealthChecks.UI

Once the installation is complete, configure the package in the ConfigureServices and Configure methods of the Startup class.

public void ConfigureServices(IServiceCollection services)
{
	services.AddHealthChecksUI();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHealthChecks("/health", new HealthCheckOptions
{
	Predicate = _ => true,
	ResponseWriter =
	UIResponseWriter.WriteHealthCheckUIResponse
});
	app.UseHealthChecksUI();
}

Finish things off by adding the following configuration in the appsettings.json file to let HealthChecksUI know where to fetch the health check information from.

"HealthChecks-UI": {
	"HealthChecks": [
  	{
    	"Name": "Local",
    	"Uri": "http://localhost:1994/health"
  	}
	],
	"EvaluationTimeOnSeconds": 10,
	"MinimumSecondsBetweenFailureNotifications": 60
  }

Fire up your application and navigate to /healthchecks-ui to see your health check in action!