.NET Custom Health Checks for Web Applications

.NET Custom Health Checks for Web APIs: A Complete Guide

In modern web applications, ensuring system health and uptime is crucial. Imagine your users experiencing slow responses or even downtime—this can severely impact user trust and business revenue. This is where health checks come into play.

With .NET Health Checks, you can monitor your application's components, such as databases, external services, and system resources, in real-time. But while built-in health checks are useful, custom health checks offer tailored solutions for complex requirements.

In this guide, you'll learn how to implement custom health checks in .NET Core, best practices, and real-world use cases to enhance application monitoring and reliability.


Why Are Health Checks Important?

Benefits of Health Checks

  • Proactive Monitoring – Detect issues before they impact users.
  • Improved Reliability – Ensure APIs and dependencies are available.
  • Seamless Deployment – Automate health verification in CI/CD pipelines.
  • Reduced Downtime – Enable automated recovery or scaling strategies.

Common Use Cases

  • Database Connectivity Monitoring – Ensure databases are reachable.
  • External API Availability – Check if third-party services are responsive.
  • Custom Business Logic Checks – Verify application-specific constraints.

Implementing Custom Health Checks in .NET Core

1. Setting Up Health Checks in .NET Core

First, install the required NuGet package:

Install-Package Microsoft.AspNetCore.Diagnostics.HealthChecks

Then, register health checks in Program.cs:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();
var app = builder.Build();
app.UseHealthChecks("/health");
app.Run();

Now, visiting https://localhost:5001/health will return a basic health status.


2. Creating a Custom Health Check

A custom health check is useful when monitoring specific application logic. Let’s create one that checks disk space availability.

Create the Custom Health Check Class

using Microsoft.Extensions.Diagnostics.HealthChecks;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

public class DiskSpaceHealthCheck : IHealthCheck
{
    private const long MinimumFreeBytes = 500000000; // 500MB

    public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        var drive = new DriveInfo("C");
        return Task.FromResult(drive.AvailableFreeSpace >= MinimumFreeBytes
            ? HealthCheckResult.Healthy("Sufficient disk space available.")
            : HealthCheckResult.Unhealthy("Low disk space!"));
    }
}

Register the Custom Health Check

In Program.cs, add:

builder.Services.AddHealthChecks()
    .AddCheck<DiskSpaceHealthCheck>("Disk Space Check");

Now, when you visit /health, it will indicate whether the disk space is sufficient.


3. Adding Multiple Health Checks

You can register multiple checks, including database, API, and memory checks:

builder.Services.AddHealthChecks()
    .AddCheck<DiskSpaceHealthCheck>("Disk Space Check")
    .AddCheck<MyCustomDatabaseHealthCheck>("Database Health Check");

Each check runs independently, providing detailed insight into system health.


Enhancing Health Checks with UI and Logging

1. Exposing Health Checks with a UI

Use AspNetCore.HealthChecks.UI to visualize health status:

Install-Package AspNetCore.HealthChecks.UI

In Program.cs:

builder.Services.AddHealthChecksUI().AddInMemoryStorage();
app.UseHealthChecksUI(options => options.UIPath = "/health-ui");

Now, access a graphical health dashboard at /health-ui.

2. Logging Health Check Failures

To log failures, integrate Serilog:

Install-Package Serilog.AspNetCore

Configure logging:

var logger = new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();
builder.Logging.AddSerilog(logger);

Best Practices for Custom Health Checks

  • Keep Health Checks Lightweight – Avoid performance-intensive checks.
  • Use Caching – Prevent excessive load on dependencies.
  • Secure Health Endpoints – Restrict access to prevent exposure.
  • Integrate with Monitoring Tools – Use Prometheus, Grafana, or Azure Monitor.

FAQs

1. What is the difference between liveness and readiness probes?

  • Liveness probes check if the application is running.
  • Readiness probes determine if the application is ready to accept traffic.

2. How often should health checks run?

Health checks should be frequent but efficient, typically every 30-60 seconds.

3. Can health checks trigger alerts?

Yes, integrate health checks with monitoring tools like Prometheus, Datadog, or Azure Monitor for alerts.

4. Is it necessary to secure health check endpoints?

Yes, expose them only to trusted sources to prevent data leaks.

5. Can I use health checks in microservices?

Absolutely! They are essential for service discovery, auto-scaling, and load balancing.


Conclusion

Custom health checks in .NET Core provide deep visibility into application health, ensuring better reliability and monitoring. By leveraging custom checks, logging, and monitoring dashboards, you can proactively detect and resolve issues before they impact users.

Want to stay updated with more .NET performance tips? 

For more in-depth .NET development guides, bookmark our blog and follow us on LinkedIn!

Sandip Mhaske

I’m a software developer exploring the depths of .NET, AWS, Angular, React, and digital entrepreneurship. Here, I decode complex problems, share insightful solutions, and navigate the evolving landscape of tech and finance.

Post a Comment

Previous Post Next Post