A Health Check library for ASP.NET Core.
| Package | Appveyor build | NuGet package |
|---|---|---|
| Groomgy.HealthChecks.AspNetCore | ||
| Groomgy.HealthChecks.AspNetCore.Sqlite | ||
| Groomgy.HealthChecks.AspNetCore.Orleans |
Install the healthchecks library with the following command:
Install-Package Groomgy.HealthChecks.AspNetCore
The library contains an extension on the IServiceCollection which provides an Action<IHealthCheckBuilder>.
The builder allows to register different healthchecks.
For example here we are registering a self check which would directly reply OK 200 with a message MyApi is running and a Url check which would GET the endpoint provided.
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks(c =>
{
c.AddSelfCheck("MyApi is running.");
c.AddUrlCheck("Authority is accessible.", "https://my-identity/.well-known/openid-configuration");
});
}
It is also possible to add custom healthchecks with c.Add(...) which takes a function providing the service provider and expect an implementation of IHealthCheck.
Then we use the healthchecks by registering the middleware on the IApplicationBuilder.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHealthChecksEndpoint();
}
The service collection extension also register a IHealthCheckService which can be used by dependency injection.
public class MyClass
{
IHealthCheckService _service;
public MyClass(IHealthCheckService service)
{
_service = serivce;
}
public async Task Check()
{
var results = await _service.CheckAll();
...
}
}
The result will be a CompositeHealthCheckResult which combine all checks together and return a failure if any of the check fails.
{
"results": [
{
"name": "SelfCheck",
"status": "Healthy",
"message": "WebA is running."
},
{
"name": "UrlCheck",
"status": "Healthy",
"message": "Successfully contacted url 'https://my-identity/.well-known/openid-configuration'. Message: Authority is accessible."
}
],
"compositeStatus": "Healthy"
}
If for example, the remote dependency is not accessible, the check will be unhealthy.
{
"results": [
{
"name": "SelfCheck",
"status": "Healthy",
"message": "WebA is running."
},
{
"name": "UrlCheck",
"status": "Unhealthy",
"message": "Failed to contact url 'https://my-identity/.well-known/openid-configuration'. Message: The delegate executed asynchronously through TimeoutPolicy did not complete within the timeout."
}
],
"compositeStatus": "Unhealthy"
}
The default UrlCheck implements two Polly policies, WaitAndRetry and Timeout.
public static IAsyncPolicy<HttpResponseMessage> WaitAndRetry(int retryCount = 5) =>
HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == HttpStatusCode.NotFound)
.Or<TimeoutRejectedException>()
.WaitAndRetryAsync(retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
public static IAsyncPolicy<HttpResponseMessage> Timeout(int seconds = 2) =>
Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(seconds));
An extension on the service collection can be used to override those policies and set your own. For example if we do not want the WaitAndRetry but only want the Timeout, we could do it like so:
services.AddHealthChecks(c => ..., new[] { PolicyHandler.Timeout(2) });
The default endpint is on /health but can be overriden with the configuration in appsettings.json:
{
"endpoints": {
"health": "/internal/__health"
}
}
The Sqlite healtcheck can be used to check the exitence of database and tables. Install the extension with the following command:
Install-Package Groomgy.HealthChecks.AspNetCore.Sqlite
And register the healthcheck:
c.AddSqliteCheck("[myconnectionstring]", "tableA", "tableB");
The existence of tableA and tableB will be checked against the database from the connection string provided.
For Microsoft.Orleans, the healtcheck is build to ensure that the client can access the Orleans cluster. It is done via a single grain implementing the IAmAlive grain interface.
Install the extension with the following command:
Install-Package Groomgy.HealthChecks.AspNetCore.Orleans
The extension needs to be installed in the projects:
- Client project
- Grain project
From the client project, register the
var client = builder
.ConfigureApplicationParts(partManager =>
{
// ... other application part
partManager.AddApplicationPart(typeof(IIAmAlive).Assembly).WithReferences();
})
.Build();
Next create the grain in your grain project:
[StatelessWorker]
public class IAmAliveGrain : Grain, IIAmAlive
{
public Task<bool> Check()
{
return Task.FromResult(true);
}
}
Lastly register the healthcheck:
c.AddOrleansClientCheck();
MIT