Help us improve
Share bugs, ideas, or general feedback.
From dotnet-clean-architecture-skills
Configures health checks for .NET apps: database (PostgreSQL), external HTTP services, Redis, RabbitMQ, and custom checks. Includes liveness/readiness endpoints for container orchestration.
npx claudepluginhub ronnythedev/dotnet-clean-architecture-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/dotnet-clean-architecture-skills:17-dotnet-health-checksThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Health checks monitor application dependencies:
Implements liveness, readiness, startup, and deep health check endpoints with dependency monitoring. Use for Kubernetes probes, load balancers, auto-scaling, or fixing probe failures and startup delays.
Implements /health and /ready endpoints for liveness and readiness probes in container orchestration platforms like Kubernetes. Includes example with Express, Prisma, and Redis.
Wires health-check endpoints (/health, /readyz, /livez) in Go services using xgodev/boost/extra/health. Covers liveness vs readiness, checkers, and aggregation.
Share bugs, ideas, or general feedback.
Health checks monitor application dependencies:
| Check Type | Purpose |
|---|---|
AddNpgSql | PostgreSQL database |
AddUrlGroup | External HTTP endpoints |
AddRedis | Redis cache |
AddRabbitMQ | RabbitMQ message broker |
| Custom | Application-specific checks |
// src/{name}.infrastructure/HealthChecks/HealthCheckExtensions.cs
using Microsoft.Extensions.Diagnostics.HealthChecks;
namespace {name}.infrastructure.healthchecks;
public static class HealthCheckExtensions
{
public static IServiceCollection AddHealthChecks(
this IServiceCollection services,
IConfiguration configuration)
{
services.AddHealthChecks()
// ═══════════════════════════════════════════════════════════════
// DATABASE
// ═══════════════════════════════════════════════════════════════
.AddNpgSql(
configuration.GetConnectionString("Database")!,
name: "postgresql",
failureStatus: HealthStatus.Unhealthy,
tags: new[] { "db", "sql", "postgresql", "ready" })
// ═══════════════════════════════════════════════════════════════
// EXTERNAL SERVICES
// ═══════════════════════════════════════════════════════════════
.AddUrlGroup(
new Uri(configuration["AuthService:BaseUrl"]!),
name: "auth-service",
failureStatus: HealthStatus.Degraded,
tags: new[] { "external", "auth", "ready" })
// ═══════════════════════════════════════════════════════════════
// REDIS (if used)
// ═══════════════════════════════════════════════════════════════
// .AddRedis(
// configuration.GetConnectionString("Redis")!,
// name: "redis",
// tags: new[] { "cache", "redis", "ready" })
// ═══════════════════════════════════════════════════════════════
// CUSTOM CHECKS
// ═══════════════════════════════════════════════════════════════
.AddCheck<DatabaseMigrationHealthCheck>(
"database-migrations",
tags: new[] { "db", "migrations", "ready" });
return services;
}
}
// src/{name}.infrastructure/HealthChecks/DatabaseMigrationHealthCheck.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Diagnostics.HealthChecks;
namespace {name}.infrastructure.healthchecks;
internal sealed class DatabaseMigrationHealthCheck : IHealthCheck
{
private readonly ApplicationDbContext _dbContext;
public DatabaseMigrationHealthCheck(ApplicationDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default)
{
try
{
var pendingMigrations = await _dbContext.Database
.GetPendingMigrationsAsync(cancellationToken);
var pending = pendingMigrations.ToList();
if (pending.Any())
{
return HealthCheckResult.Degraded(
$"Pending migrations: {string.Join(", ", pending)}",
data: new Dictionary<string, object>
{
{ "pending_count", pending.Count },
{ "migrations", pending }
});
}
return HealthCheckResult.Healthy("All migrations applied");
}
catch (Exception ex)
{
return HealthCheckResult.Unhealthy(
"Failed to check migrations",
exception: ex);
}
}
}
// src/{name}.api/Program.cs
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
var app = builder.Build();
// ═══════════════════════════════════════════════════════════════
// LIVENESS: Is the app running?
// ═══════════════════════════════════════════════════════════════
app.MapHealthChecks("/health/live", new HealthCheckOptions
{
Predicate = _ => false, // No checks, just confirms app is running
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
// ═══════════════════════════════════════════════════════════════
// READINESS: Is the app ready to serve traffic?
// ═══════════════════════════════════════════════════════════════
app.MapHealthChecks("/health/ready", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("ready"),
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
// ═══════════════════════════════════════════════════════════════
// FULL: All health checks
// ═══════════════════════════════════════════════════════════════
app.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: api
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
dotnet-clean-architecture - Infrastructure layer setupdotnet-jwt-authentication - Auth service health check