DEV Community

Supratim Roy
Supratim Roy

Posted on

Building Resilient Apps: Health Checks in ASP.NET Core

In today’s fast-paced digital world, application reliability is critical. A single failure in a database, external API, or caching service can impact performance and lead to downtime. Health checks in ASP.NET Core help monitor the status of your app and its dependencies, ensuring smooth operation and proactive issue detection. They provide a simple way to check system health, notify monitoring tools, and even help with load balancing in cloud environments.

In this post, we'll explore how to implement health checks in ASP.NET Core to keep your application running smoothly and resilient against failures.

In ASP.NET Core, you can implement health checks using the built-in Microsoft.AspNetCore.Diagnostics.HealthChecks middleware. Health checks help monitor the status of your application and its dependencies (like databases, external APIs, etc.).

ASP.NET Core has built-in support for health checks, but if you need UI support or database checks, install additional packages:

dotnet add package AspNetCore.HealthChecks.UI
dotnet add package AspNetCore.HealthChecks.UI.Client
dotnet add package Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
Enter fullscreen mode Exit fullscreen mode

First, add the health checks middleware in your Program.cs (for .NET 6+) or Startup.cs (older versions):

// Program.cs
var builder = WebApplication.CreateBuilder(args);

// Add health checks
builder.Services.AddHealthChecks();

var app = builder.Build();

// Add health check endpoint
app.UseHealthChecks("/health");

app.Run();
Enter fullscreen mode Exit fullscreen mode

For a more detailed implementation with specific checks, here's an example:

// Program.cs
var builder = WebApplication.CreateBuilder(args);

// Add health checks with specific checks
builder.Services.AddHealthChecks()
    .AddMemoryHealthCheck("memory", maximumMemoryBytes: 104857600) // 100MB
    .AddDiskStorageHealthCheck(setup =>
        setup.AddDrive("C:\\", minimumFreeMegabytes: 1000)) // 1GB free
    .AddUrlGroup(new Uri("https://api.example.com"), "external-api-check");

var app = builder.Build();

// Configure health check endpoint with response
app.UseHealthChecks("/health", new HealthCheckOptions
{
    ResponseWriter = async (context, report) =>
    {
        context.Response.ContentType = "application/json";
        var response = new
        {
            status = report.Status.ToString(),
            checks = report.Entries.Select(e => new
            {
                name = e.Key,
                status = e.Value.Status.ToString(),
                description = e.Value.Description
            })
        };
        await context.Response.WriteAsJsonAsync(response);
    }
});

app.Run();
Enter fullscreen mode Exit fullscreen mode

To add custom health checks, create a class implementing IHealthCheck:

public class CustomHealthCheck : IHealthCheck
{
    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        // Your custom health check logic
        bool isHealthy = CheckSomeCondition();

        return Task.FromResult(
            isHealthy
                ? HealthCheckResult.Healthy("System is healthy")
                : HealthCheckResult.Unhealthy("System is unhealthy"));
    }

    private bool CheckSomeCondition()
    {
        // Implement your condition checking logic
        return true;
    }
}

// Register it in Program.cs
builder.Services.AddHealthChecks()
    .AddCheck<CustomHealthCheck>("custom_check");
Enter fullscreen mode Exit fullscreen mode

You can also add health check UI (optional):

// Add NuGet package: AspNetCore.HealthChecks.UI
builder.Services.AddHealthChecksUI()
    .AddInMemoryStorage();

app.UseHealthChecksUI(config =>
{
    config.UIPath = "/health-ui"; // Access at /health-ui
});
Enter fullscreen mode Exit fullscreen mode

Common Health Check Types You Can Add:

  • .AddSqlServer(connectionString) - SQL Server check
  • .AddRedis(redisConnectionString) - Redis check
  • .AddNpgSql(connectionString) - PostgreSQL check
  • .AddMongoDb(mongodbConnectionString) - MongoDB check

Usage Example:

public class MyService
{
    private readonly IHealthCheckService _healthCheckService;

    public MyService(IHealthCheckService healthCheckService)
    {
        _healthCheckService = healthCheckService;
    }

    public async Task CheckHealthAsync()
    {
        var result = await _healthCheckService.CheckHealthAsync();
        if (result.Status == HealthStatus.Healthy)
        {
            // Handle healthy state
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Key Points:

  • Default endpoint is /health
  • Returns HTTP 200 for healthy, 503 for unhealthy
  • Can be used with load balancers
  • Supports dependency injection
  • Can be secured with authorization

To Test:

  1. Run your app
  2. Navigate to http://localhost:port/health
  3. For UI (if added): http://localhost:port/health-ui

Use Cases:

  • Application monitoring: Check database, cache, and API status.
  • Load balancer health checks: Route traffic only to healthy instances.
  • Kubernetes readiness and liveness probes: Ensure smooth deployments.

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay