What are health checks in ASP.NET Core?
4 minintermediateASP.NET-Corehealth-checksobservability
Quick Answer
Health checks report the liveness/readiness of an app and its dependencies (database, cache, external services) via `AddHealthChecks` and a `/health` endpoint. Custom checks implement `IHealthCheck` and return Healthy/Degraded/Unhealthy; results can be filtered by tags and consumed by load balancers, Kubernetes probes, or orchestrators to route traffic and trigger restarts.
Detailed Answer
Health Checks allow you to monitor the health and availability of your application and its dependencies.
Basic Implementation:
// Program.cs
builder.Services.AddHealthChecks()
.AddCheck("self", () => HealthCheckResult.Healthy())
.AddSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection"),
name: "database",
timeout: TimeSpan.FromSeconds(5))
.AddUrlGroup(
new Uri("https://api.external.com/health"),
name: "external-api",
timeout: TimeSpan.FromSeconds(3))
.AddRedis(
builder.Configuration.GetConnectionString("Redis"),
name: "redis");
app.MapHealthChecks("/health");
Custom Health Check:
public class CustomHealthCheck : IHealthCheck
{
private readonly IHttpClientFactory _httpClientFactory;
public CustomHealthCheck(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default)
{
try
{
var client = _httpClientFactory.CreateClient();
var response = await client.GetAsync("https://api.example.com/status");
if (response.IsSuccessStatusCode)
{
return HealthCheckResult.Healthy("External API is responding");
}
return HealthCheckResult.Degraded("External API returned non-success status");
}
catch (Exception ex)
{
return HealthCheckResult.Unhealthy("External API is not accessible", ex);
}
}
}
// Register
builder.Services.AddHealthChecks()
.AddCheck("custom-check");
Health Check with Detailed Response:
app.MapHealthChecks("/health/detailed", new HealthCheckOptions
{
ResponseWriter = async (context, report) =>
{
context.Response.ContentType = "application/json";
var result = JsonSerializer.Serialize(new
{
status = report.Status.ToString(),
checks = report.Entries.Select(e => new
{
name = e.Key,
status = e.Value.Status.ToString(),
description = e.Value.Description,
duration = e.Value.Duration.ToString()
}),
totalDuration = report.TotalDuration
});
await context.Response.WriteAsync(result);
}
});
Health Check with Tags:
builder.Services.AddHealthChecks()
.AddSqlServer(
connectionString,
name: "database",
tags: new[] { "db", "sql" })
.AddRedis(
redisConnection,
name: "cache",
tags: new[] { "cache", "redis" });
// Endpoint for specific tags
app.MapHealthChecks("/health/ready", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("ready")
});
app.MapHealthChecks("/health/live", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("live")
});
Health Check UI (Optional Package):
dotnet add package AspNetCore.HealthChecks.UI
dotnet add package AspNetCore.HealthChecks.UI.InMemory.Storage
builder.Services
.AddHealthChecksUI()
.AddInMemoryStorage();
app.MapHealthChecksUI();
// Access UI at: /healthchecks-ui
Common Use Cases:
- Kubernetes liveness and readiness probes
- Load balancer health endpoints
- Monitoring and alerting systems
- Circuit breaker patterns
- Graceful degradation
Example Response:
{
"status": "Healthy",
"checks": [
{
"name": "database",
"status": "Healthy",
"description": "SQL Server is healthy",
"duration": "00:00:00.1234567"
},
{
"name": "redis",
"status": "Healthy",
"description": "Redis is healthy",
"duration": "00:00:00.0234567"
}
],
"totalDuration": "00:00:00.1469134"
}