Health
You can use the Steeltoe Health endpoint to query the status of your running application. It is often used to monitor software and alert someone if a production system goes down.
Health information is collected from all IHealthContributor
implementations registered in the application,
as well as from ASP.NET Core Health Checks.
Steeltoe includes several contributors, out-of-the-box, that you can use.
Other Steeltoe components typically add their own contributors where applicable.
In addition, you can write your own.
By default, the final application health state is computed by the registered IHealthAggregator
implementation.
It is responsible for sorting out all of the returned statuses from each IHealthContributor
and IHealthCheck
and deriving an overall application health state.
The built-in aggregator returns the worst status returned from the contributors and checks.
Configure Settings
The following table describes the configuration settings that you can apply to the endpoint.
Each key must be prefixed with Management:Endpoints:Health:
.
Key | Description | Default |
---|---|---|
Enabled |
Whether the endpoint is enabled | true |
ID |
The unique ID of the endpoint | health |
Path |
The relative path at which the endpoint is exposed | same as ID |
RequiredPermissions |
Permissions required to access the endpoint when running on Cloud Foundry | Restricted |
AllowedVerbs |
An array of HTTP verbs in which the endpoint is exposed | GET |
ShowComponents |
Whether health check components should be included in the response | Never |
ShowDetails |
Whether details of health check components should be included in the response | Never |
Claim |
The claim required in HttpContext.User when ShowComponents and/or ShowDetails is set to WhenAuthorized |
|
Role |
The role required in HttpContext.User when ShowComponents and/or ShowDetails is set to WhenAuthorized |
The depth of information exposed by the health endpoint depends on the ShowComponents
and ShowDetails
properties; both can be configured with one of the following values:
Name | Description |
---|---|
Never |
Never shown |
WhenAuthorized |
Shown only to authorized users |
Always |
Always shown |
ShowDetails
has an effect only when ShowComponents
is set to:
Always
WhenAuthorized
if the request is authorized
Authorized users can be configured by setting Claim
or Role
.
A user is considered to be authorized when they are in the given role or have the specified claim.
The following example uses Management:Endpoints:Health:Claim
:
{
"Management": {
"Endpoints": {
"Health": {
"ShowComponents": "WhenAuthorized",
"ShowDetails": "WhenAuthorized",
"Claim": {
"Type": "health_actuator",
"Value": "see_all"
}
}
}
}
}
Enable HTTP Access
The URL path to the endpoint is computed by combining the global Management:Endpoints:Path
setting with the Path
setting described in the preceding section.
The default path is /actuator/health
.
See the Exposing Endpoints and HTTP Access sections for the steps required to enable HTTP access to endpoints in an ASP.NET Core application.
To add the actuator to the service container and map its route, use the AddHealthActuator
extension method.
Add the following code to Program.cs
to use the actuator endpoint:
using Steeltoe.Management.Endpoint.Actuators.Health;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthActuator();
Tip
It is recommended that you use AddAllActuators()
instead of adding individual actuators;
this enables individually turning them on/off at runtime via configuration.
By default, the health status is reflected in the HTTP response status code.
For example, when a health check fails, the response status code is 503 Service Unavailable
.
The configuration key Management:Endpoints:UseStatusCodeFromResponse
can be set to false
, which makes the health check always respond with status code 200 OK
.
Clients can overrule this per request by sending an X-Use-Status-Code-From-Response
HTTP header with the value true
or false
.
Tip
By default, health contributors for disk space and ping are activated. They can be turned off through configuration:
{
"Management": {
"Endpoints": {
"Health": {
"DiskSpace": {
"Enabled": "false"
},
"Ping": {
"Enabled": "false"
}
}
}
}
}
Sample Output
This endpoint returns the top-level status, along with the details of the contributors and checks.
The response is always returned as JSON, and this is the default value:
{
"status": "UP"
}
When ShowComponents
and ShowDetails
are set to Always
, or when set to WhenAuthorized
and the request is authorized, the response is more detailed:
{
"status": "UP",
"components": {
"ping": {
"status": "UP"
},
"diskSpace": {
"status": "UP",
"details": {
"total": 1999599824896,
"free": 1330717282304,
"threshold": 10485760,
"path": "C:\\source\\Repository\\src\\Project",
"exists": true
}
}
}
}
Note
When using Steeltoe Connectors, Service Discovery, or Config Server in your application, the corresponding health contributors are automatically added to the service container. See their corresponding documentation for how to turn them off.
Health Groups
If you want to check application health based on a subset of health contributors, you can specify the name of the grouping and a comma-separated list of contributors to include:
{
"Management": {
"Endpoints": {
"Health": {
"Groups": {
"example-group": {
"Include": "Redis,RabbitMQ"
}
}
}
}
}
}
While group names are case-sensitive, the entries in Include
are case-insensitive and activate only health contributors with a matching Id
, and/or ASP.NET health check registrations with a matching name.
For any group that has been defined, you can access health information from the group by appending the group name to the HTTP request URL. For example: /actuator/health/example-group
.
ShowComponents
and ShowDetails
can also be set at the group level, overriding the settings found at the endpoint level.
{
"Management": {
"Endpoints": {
"Health": {
"Claim": {
"Type": "health_actuator",
"Value": "see_all"
},
"Groups": {
"example-group": {
"Include": "Redis,RabbitMQ",
"ShowComponents": "Always",
"ShowDetails": "WhenAuthorized"
}
}
}
}
}
}
Kubernetes Health Groups
Applications deployed on Kubernetes can provide information about their internal state with Container Probes. Depending on your Kubernetes configuration, the kubelet calls those probes and reacts to the result.
Steeltoe provides an ApplicationAvailability
class for managing various types of application state.
Support is provided, out of the box, for Liveness and Readiness, where each is exposed in a corresponding IHealthContributor
and health group.
While these health contributors are included, they are disabled by default and must be enabled in the configuration (as shown in the example below).
To change the health contributors that are included in either of the two built-in groups, use the same style of configuration described above.
Note that this replaces the default groupings, so if you want to add an IHealthContributor
, you must include the original entry.
The following example enables both contributors and their groups, and specifies to include disk space in both groups:
{
"Management": {
"Endpoints": {
"Health": {
"Liveness": {
"Enabled": "true"
},
"Readiness": {
"Enabled": "true"
},
"Groups": {
"liveness": {
"Include": "diskSpace,livenessState"
},
"readiness": {
"Include": "diskSpace,readinessState"
}
}
}
}
}
}
Liveness
The Liveness state of an application tells whether its internal state is valid. If Liveness is broken, this means that the application itself is in a failed state and cannot recover from it. In this case, the best course of action is to restart the application instance.
Out of the box, any of Steeltoe's extension methods that set up the health actuator initialize the liveness state with LivenessState.Correct
. The only other defined state for liveness is LivenessState.Broken
, though Steeltoe code does not currently cover any conditions that set this state.
Caution
In general, the Liveness state should not depend on external system checks such as a database, queue, or cache server. Including checks on external systems could trigger massive restarts and cascading failures across the platform.
Readiness
The Readiness state tells whether the application is ready to accept client requests. If the Readiness state is unready, the platform should not route traffic to this instance. If an application is too busy processing a task queue, then it could declare itself as busy until its load is manageable again.
Out of the box, any of Steeltoe's extension methods that set up the health actuator also:
- Register a callback on
ApplicationStarted
to initialize the readiness state toAcceptingTraffic
when the application has started - Register a callback on
ApplicationStopping
to change the state toRefusingTraffic
when the application begins to shut down
These are the only defined states for this availability type.
Managing Application Availability State
Application components can retrieve the current availability state at any time by requesting ApplicationAvailability
from the dependency injection container and calling methods on it:
[ApiController]
[Route("[controller]")]
public class AvailabilityController(ApplicationAvailability applicationAvailability) : ControllerBase
{
[HttpGet]
public string Get()
{
var readinessState = applicationAvailability.GetReadinessState();
var livenessState = applicationAvailability.GetLivenessState();
return $"Readiness state = {readinessState}, Liveness state = {livenessState}";
}
}
Additionally, it is possible to subscribe to changes in liveness and readiness by attaching an event handler:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthActuator();
var app = builder.Build();
var availability = app.Services.GetRequiredService<ApplicationAvailability>();
availability.LivenessChanged += (_, args) => Console.WriteLine($"Liveness state changed to {args.NewState}");
availability.ReadinessChanged += (_, args) => Console.WriteLine($"Readiness state changed to {args.NewState}");
app.Run();
Creating a Custom Health Contributor
If you want to provide custom health information for your application:
- Create a class that implements the
IHealthContributor
interface. - Add the new class to the service container.
The following example contributor always returns a HealthStatus
of WARNING
:
using Steeltoe.Common.HealthChecks;
using Steeltoe.Management.Endpoint.Actuators.Health;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthActuator();
builder.Services.AddHealthContributor<ExampleHealthContributor>();
public class ExampleHealthContributor : IHealthContributor
{
public string Id => nameof(ExampleHealthContributor);
public Task<HealthCheckResult?> CheckHealthAsync(CancellationToken cancellationToken)
{
HealthCheckResult? status = GetStatus();
return Task.FromResult(status);
}
private static HealthCheckResult? GetStatus()
{
return new HealthCheckResult
{
Status = HealthStatus.Warning,
Description = "This health check does not check anything"
};
}
}
Sending a GET request to /actuator/health
returns the following response:
{
"status":"WARNING"
}
When ShowComponents
and ShowDetails
are set to Always
, or when set to WhenAuthorized
and the request is authorized, the response is more detailed:
{
"status": "WARNING",
"components": {
"ExampleHealthContributor": {
"status": "WARNING",
"description": "This health check does not check anything"
},
"ping": {
"status": "UP"
},
"diskSpace": {
"status": "UP",
"details": {
"total": 1999599824896,
"free": 1330717282304,
"threshold": 10485760,
"path": "C:\\source\\Repository\\src\\Project",
"exists": true
}
}
}
}
ASP NET Core Health Checks
ASP.NET Core offers middleware and libraries and abstractions for reporting health. There is wide community support for these abstractions from libraries such as AspNetCore.Diagnostics.HealthChecks. You can use these community-provided health checks and make them available using the health actuator (for integration with Cloud Foundry or any other infrastructure that depends on this format). In addition, Steeltoe Connectors expose functionality to get the connection string, which is needed to set up these community health checks.
For example, to use the Steeltoe MySQL connector, but replace its health contributor with the ASP.NET Core community health check,
use the following code in Program.cs
:
using Microsoft.Extensions.Options;
using Steeltoe.Connectors.MySql;
using Steeltoe.Management.Endpoint.Actuators.Health;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthActuator();
// Add the Steeltoe Connector for MySQL, but turn off its health contributor.
builder.AddMySql(null, options => options.EnableHealthChecks = false);
// Add the community-based ASP.NET health check, obtaining the connection string from Steeltoe.
builder.Services.AddHealthChecks().AddMySql(serviceProvider =>
{
var options = serviceProvider.GetRequiredService<IOptions<MySqlOptions>>();
return options.Value.ConnectionString!;
});
The code above assumes the following appsettings.json
configuration, combined with the Steeltoe docker container for MySQL:
{
"Steeltoe": {
"Client": {
"MySql": {
"Default": {
"ConnectionString": "SERVER=localhost;Database=steeltoe;UID=steeltoe;PWD=steeltoe"
}
}
}
}
}