Introduction
Ensuring the health and reliability of your applications is important for minimizing lost revenue and maximizing the user experience.
By adding health checks to your application, you can continuously monitor the pulse of applications, assess vital signs, and preemptively detect anomalies before they become critical issues. Whether its database connectivity, external dependencies, or other custom application-specific checks, health checks provide you with a comprehensive and proactive view of an application’s well-being.
In this blog, I’ll delve into the world of health checks in .NET, exploring what they are, why they matter, and how to implement them effectively.
Why Health Checks Matter
Health checks offer several benefits to developers, users, and operations teams:
- Proactive Monitoring: Health checks enable proactive monitoring of application components, helping teams identify and resolve issues before they impact end-users.
- Improved Reliability: By continuously assessing the health of your application, you can maintain high reliability and uptime, thereby enhancing user experience and trust.
- Faster Troubleshooting: Health checks provide valuable insights into the root causes of potential problems, enabling teams to troubleshoot and resolve issues more efficiently.
- Automated Remediation: When integrated with automated alerting and remediation systems, health checks can trigger automatic responses to resolve issues, reducing manual intervention and downtime.
Implementing Health Checks in .NET
In the .NET ecosystem, implementing health checks is straightforward, thanks to built-in support provided by frameworks like ASP.NET Core. Let’s explore how you can integrate health checks into your ASP.NET CORE applications with the Health Checks Middleware:
1. Using ASP.NET Core Health Checks Middleware
ASP.NET Core provides a powerful Health Checks Middleware that allows you to define custom health checks for your application. Here’s a basic example of how to set up health checks in an ASP.NET Core application:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapHealthChecks("/healthz");
app.Run();
Or, if you’re still using the older style Startup.cs in your ASP.NET Core project:
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHealthChecks("/healthz");
}
In this example, we’ve added the Health Checks Middleware to our application pipeline and specified the endpoint (“/healthz”) where health check results will be exposed.
Note: Metadata endpoints like this often use a “z” as a suffix to help ensure there is no collision with similarly-named endpoints exposed by the application itself.
2. Implementing Custom Health Checks
You can also create custom health checks tailored to your application’s specific requirements. Here’s how you can define a custom health check in .NET:
public class CustomHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
// Perform health check logic here
bool isHealthy = true; // Example health check logic
if (isHealthy)
{
return Task.FromResult(HealthCheckResult.Healthy("Custom check is healthy."));
}
else
{
return Task.FromResult(HealthCheckResult.Unhealthy("Custom check is unhealthy."));
}
}
}
In this example, we’ve implemented the IHealthCheck interface and overridden the CheckHealthAsync method to perform custom health check logic. Depending on the result of the health check, we return either a Healthy or Unhealthy status along with an optional description.
3. Monitoring External Dependencies
You can also use health checks to monitor external dependencies such as databases, APIs, and services. ASP.NET Core provides built-in health check probes for common dependencies like SQL Server, Redis, and Azure Service Bus.
public class DatabaseHealthCheck : IHealthCheck
{
private readonly string _connectionString;
public DatabaseHealthCheck(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("DefaultConnection");
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
using (var connection = new SqlConnection(_connectionString))
{
await connection.OpenAsync(cancellationToken);
if (connection.State == System.Data.ConnectionState.Open)
{
return HealthCheckResult.Healthy("Database connection is healthy.");
}
else
{
return HealthCheckResult.Unhealthy("Database connection is not open.");
}
}
}
catch (Exception ex)
{
return HealthCheckResult.Unhealthy("Exception during database connection: " + ex.Message);
}
}
}
Next Steps
Once health checks are implemented as an endpoint in your application, they will need to be monitored from a central location or system to be useful. This process is commonly referred to as “health check monitoring” or “health monitoring.” It involves regularly checking the results of your health checks to ensure that all components of the application are functioning as expected.
Azure Application Insights is one of the services available to you that will do just that. It allows you to monitor the availability, performance, and usage of your web applications and services through endpoints you configure. Within Application Insights, you can set up different availability tests that periodically check the health of your application, even from different geographic locations. You can then use its robust alerting system to let the right groups know when there is an issue.
Conclusion
Health checks are a fundamental aspect of modern application development, providing invaluable insights into the operational state and reliability of your applications. By implementing health checks in your .NET applications, you can proactively monitor critical components, ensure high availability, and deliver a seamless user experience.
In this guide, we’ve explored the importance of health checks, their benefits, and how to implement them effectively using ASP.NET. By incorporating health checks into your development workflow, you can build robust, reliable, and resilient applications that meet the demands of today’s dynamic software landscape.
If you’d like help setting up health checks in your application, Trailhead can help with that. Just contact us to get the process started.


