The Intent.AspNetCore.HealthChecks module enables comprehensive health monitoring for your ASP.NET Core application, allowing you to determine if your application and its dependencies are responding normally.
Overview
Health checks provide endpoints that external monitoring tools can query to verify your application’s health. This is essential for container orchestrators (Kubernetes, Docker Swarm), load balancers, and monitoring systems.
What Gets Generated
HealthChecksConfiguration
Configures health check endpoints and UI:
public static class HealthChecksConfiguration
{
public static IServiceCollection AddHealthChecksConfiguration (
this IServiceCollection services ,
IConfiguration configuration )
{
var healthChecksBuilder = services . AddHealthChecks ();
// Add database health check if using Entity Framework
healthChecksBuilder . AddDbContextCheck < ApplicationDbContext >();
// Configure health checks UI if enabled
var healthChecksSettings = configuration
. GetSection ( "HealthChecks" )
. Get < HealthChecksSettings >();
if ( healthChecksSettings ? . HealthChecksUI ?? false )
{
services . AddHealthChecksUI ( setup =>
{
setup . AddHealthCheckEndpoint ( "API Health Check" , "/health" );
})
. AddInMemoryStorage ();
}
return services ;
}
public static IApplicationBuilder UseHealthChecksConfiguration (
this IApplicationBuilder app )
{
app . UseHealthChecks ( "/health" , new HealthCheckOptions
{
ResponseWriter = UIResponseWriter . WriteHealthCheckUIResponse
});
app . UseHealthChecks ( "/health/ready" , new HealthCheckOptions
{
Predicate = check => check . Tags . Contains ( "ready" ),
ResponseWriter = UIResponseWriter . WriteHealthCheckUIResponse
});
app . UseHealthChecks ( "/health/live" , new HealthCheckOptions
{
Predicate = _ => false , // Exclude all checks, just ping
ResponseWriter = UIResponseWriter . WriteHealthCheckUIResponse
});
return app ;
}
}
Key Features
Database Checks Monitor database connectivity and health
Dependency Checks Check external service dependencies
Custom Checks Create application-specific health checks
Health UI Optional dashboard for monitoring health
Module Settings
Publish Events
Specify where to publish events for monitoring health status availability Options:
none - No event publishing
azure-application-insights - Publish to Azure Application Insights
Health Checks UI
Enable Health Checks UI - a minimal UI interface that monitors your app’s health check state
Health Check Endpoints
The module creates three standard endpoints:
/health
Overall application health:
GET /health HTTP / 1.1
HTTP / 1.1 200 OK
Content-Type : application/json
{
"status" : "Healthy" ,
"totalDuration" : "00:00:00.0234567" ,
"entries" : {
"ApplicationDbContext" : {
"status" : "Healthy" ,
"duration" : "00:00:00.0123456" ,
"data" : {}
},
"Redis" : {
"status" : "Healthy" ,
"duration" : "00:00:00.0098765" ,
"data" : {}
}
}
}
/health/ready
Readiness probe (all dependencies ready):
GET /health/ready HTTP / 1.1
HTTP / 1.1 200 OK
{
"status" : "Healthy"
}
/health/live
Liveness probe (application is running):
GET /health/live HTTP / 1.1
HTTP / 1.1 200 OK
{
"status" : "Healthy"
}
Health Status Codes
Health checks return different HTTP status codes:
200 OK - Healthy
503 Service Unavailable - Unhealthy
200 OK (with Degraded status) - Degraded
Built-in Health Checks
Database Health Check
Automatically added for Entity Framework:
healthChecksBuilder . AddDbContextCheck < ApplicationDbContext >();
SQL Server
healthChecksBuilder . AddSqlServer (
connectionString : configuration . GetConnectionString ( "DefaultConnection" ),
name : "sql-server" ,
tags : new [] { "db" , "sql" , "ready" });
Redis
healthChecksBuilder . AddRedis (
redisConnectionString : configuration . GetConnectionString ( "Redis" ),
name : "redis" ,
tags : new [] { "cache" , "redis" , "ready" });
Azure Services
// Azure Service Bus
healthChecksBuilder . AddAzureServiceBusQueue (
connectionString : configuration [ "Azure:ServiceBus:ConnectionString" ],
queueName : "orders-queue" ,
name : "azure-service-bus" );
// Azure Blob Storage
healthChecksBuilder . AddAzureBlobStorage (
connectionString : configuration [ "Azure:Storage:ConnectionString" ],
name : "azure-blob-storage" );
External HTTP Services
healthChecksBuilder . AddUrlGroup (
new Uri ( "https://api.external-service.com/health" ),
name : "external-api" ,
tags : new [] { "external" , "ready" });
Custom Health Checks
Create application-specific health checks:
Simple Health Check
public class CustomHealthCheck : IHealthCheck
{
public Task < HealthCheckResult > CheckHealthAsync (
HealthCheckContext context ,
CancellationToken cancellationToken = default )
{
var isHealthy = CheckSomeCondition ();
if ( isHealthy )
{
return Task . FromResult (
HealthCheckResult . Healthy ( "Custom check passed" ));
}
return Task . FromResult (
HealthCheckResult . Unhealthy ( "Custom check failed" ));
}
private bool CheckSomeCondition ()
{
// Your custom logic here
return true ;
}
}
// Register
services . AddHealthChecks ()
. AddCheck < CustomHealthCheck >( "custom-check" );
Health Check with Dependencies
public class OrderProcessingHealthCheck : IHealthCheck
{
private readonly IOrderService _orderService ;
private readonly ILogger < OrderProcessingHealthCheck > _logger ;
public OrderProcessingHealthCheck (
IOrderService orderService ,
ILogger < OrderProcessingHealthCheck > logger )
{
_orderService = orderService ;
_logger = logger ;
}
public async Task < HealthCheckResult > CheckHealthAsync (
HealthCheckContext context ,
CancellationToken cancellationToken = default )
{
try
{
var pendingCount = await _orderService
. GetPendingOrdersCountAsync ( cancellationToken );
if ( pendingCount > 1000 )
{
return HealthCheckResult . Degraded (
$"High number of pending orders: { pendingCount } " ,
data : new Dictionary < string , object >
{
{ "PendingOrders" , pendingCount }
});
}
return HealthCheckResult . Healthy (
$"Order processing is healthy. Pending: { pendingCount } " ,
data : new Dictionary < string , object >
{
{ "PendingOrders" , pendingCount }
});
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Order processing health check failed" );
return HealthCheckResult . Unhealthy (
"Failed to check order processing" ,
exception : ex );
}
}
}
// Register
services . AddHealthChecks ()
. AddCheck < OrderProcessingHealthCheck >(
"order-processing" ,
tags : new [] { "business" , "ready" });
Memory Health Check
public class MemoryHealthCheck : IHealthCheck
{
private const long Threshold = 1024L * 1024L * 1024L ; // 1 GB
public Task < HealthCheckResult > CheckHealthAsync (
HealthCheckContext context ,
CancellationToken cancellationToken = default )
{
var allocated = GC . GetTotalMemory ( forceFullCollection : false );
var data = new Dictionary < string , object >
{
{ "AllocatedBytes" , allocated },
{ "Gen0Collections" , GC . CollectionCount ( 0 ) },
{ "Gen1Collections" , GC . CollectionCount ( 1 ) },
{ "Gen2Collections" , GC . CollectionCount ( 2 ) }
};
var status = allocated < Threshold
? HealthStatus . Healthy
: HealthStatus . Degraded ;
return Task . FromResult ( new HealthCheckResult (
status ,
description : $"Reports degraded status if allocated memory >= { Threshold } bytes." ,
data : data ));
}
}
Tagging Health Checks
Organize health checks with tags:
services . AddHealthChecks ()
. AddDbContextCheck < ApplicationDbContext >(
name : "database" ,
tags : new [] { "db" , "sql" , "ready" })
. AddRedis (
configuration [ "Redis:ConnectionString" ],
name : "redis" ,
tags : new [] { "cache" , "ready" })
. AddCheck < OrderProcessingHealthCheck >(
"order-processing" ,
tags : new [] { "business" });
Filter by tags in endpoints:
app . UseHealthChecks ( "/health/ready" , new HealthCheckOptions
{
Predicate = check => check . Tags . Contains ( "ready" )
});
app . UseHealthChecks ( "/health/db" , new HealthCheckOptions
{
Predicate = check => check . Tags . Contains ( "db" )
});
Health Checks UI
When enabled, provides a web interface:
services . AddHealthChecksUI ( setup =>
{
setup . SetEvaluationTimeInSeconds ( 30 ); // Check every 30 seconds
setup . MaximumHistoryEntriesPerEndpoint ( 50 );
setup . AddHealthCheckEndpoint ( "API" , "/health" );
})
. AddInMemoryStorage ();
app . UseHealthChecksUI ( options =>
{
options . UIPath = "/health-ui" ;
options . ApiPath = "/health-ui-api" ;
});
Access the UI at: https://localhost:5001/health-ui
Kubernetes Integration
Liveness Probe
Checks if the container should be restarted:
apiVersion : v1
kind : Pod
metadata :
name : my-api
spec :
containers :
- name : api
image : my-api:latest
livenessProbe :
httpGet :
path : /health/live
port : 80
initialDelaySeconds : 30
periodSeconds : 10
timeoutSeconds : 5
failureThreshold : 3
Readiness Probe
Checks if the container is ready to receive traffic:
readinessProbe :
httpGet :
path : /health/ready
port : 80
initialDelaySeconds : 5
periodSeconds : 10
timeoutSeconds : 5
successThreshold : 1
failureThreshold : 3
Startup Probe
Checks if the application has started:
startupProbe :
httpGet :
path : /health/live
port : 80
initialDelaySeconds : 0
periodSeconds : 10
timeoutSeconds : 5
failureThreshold : 30
Docker Compose
services :
api :
image : my-api:latest
healthcheck :
test : [ "CMD" , "curl" , "-f" , "http://localhost/health" ]
interval : 30s
timeout : 10s
retries : 3
start_period : 40s
Azure Application Insights
Publish health check events to Application Insights:
services . AddHealthChecks ()
. AddApplicationInsightsPublisher (
instrumentationKey : configuration [ "ApplicationInsights:InstrumentationKey" ],
saveDetailedReport : true );
Monitoring and Alerting
Azure Monitor
Create availability test:
az monitor app-insights component create \
--app my-api \
--location eastus \
--resource-group my-rg
az monitor app-insights web-test create \
--app my-api \
--location eastus \
--name health-check \
--web-test-url https://api.example.com/health
Prometheus
Export health checks to Prometheus:
services . AddHealthChecks ()
. ForwardToPrometheus ();
Best Practices
Keep health checks fast (< 1 second)
Don’t perform complex operations
Use timeouts for external checks
Cache results when appropriate
Check critical dependencies only
Use readiness probes for dependencies
Don’t fail liveness for dependency issues
Implement circuit breakers for external services
Don’t expose sensitive information
Consider authentication for health endpoints
Use internal endpoints for detailed checks
Limit information in public health checks
Set up alerts for unhealthy states
Monitor health check duration
Track degraded states
Log health check failures
Troubleshooting
Health Check Always Returns Unhealthy
Check dependency configuration
Verify connection strings
Review health check logs
Test dependencies independently
Reduce check complexity
Add timeout to external checks
Check network connectivity
Review database query performance
Kubernetes Keeps Restarting Pods
Increase initialDelaySeconds
Adjust failureThreshold
Check liveness vs readiness configuration
Review application startup time
Installation
Intent.AspNetCore.HealthChecks
Dependencies
Intent.Common.CSharp
Intent.Modelers.Services
Intent.OutputManager.RoslynWeaver
NuGet Packages
Common health check packages:
< PackageReference Include = "AspNetCore.HealthChecks.SqlServer" Version = "*" />
< PackageReference Include = "AspNetCore.HealthChecks.Redis" Version = "*" />
< PackageReference Include = "AspNetCore.HealthChecks.AzureServiceBus" Version = "*" />
< PackageReference Include = "AspNetCore.HealthChecks.Uris" Version = "*" />
< PackageReference Include = "AspNetCore.HealthChecks.UI" Version = "*" />
Next Steps
ASP.NET Core Learn about the core infrastructure
Controllers Create API endpoints
Entity Framework Configure database health checks