Please see "You Don't Need to Use Akka.HealthChecks Anymore"
A configurable library for exposing Akka nodes inside common healthcheck systems and environments, such as Kubernetes Liveness and Readiness probes and ASP.NET health checks.
The core plugin is designed to run as standalone health check endpoint for your actor system. Three types of transports are supported:
-
Custom (default)
Used to specify that no built-in transport will be used. Typically users will query / subscribe to the Readiness or Liveness probe actors and pipe the changes in liveness / readiness status out to something like a custom HTTP endpoint.
-
TCP socket
This transport mode fulfills a Kubernetes-like style health check endpoint, where liveness/readiness are tested by checking if a pod can accept a socket connection request on a certain port. See the Kubernetes documentation for usage example.
-
File
Writes the readiness or liveness status out to disk to a specified file location. Used in combination with liveness checks such as "command line execution" checks. See the Kubernetes documentation for usage example.
There are 5 probe providers that can be used with Akka.HealthCheck:
DefaultReadinessProvider- The default readiness probe. The probe reports the time theActorSystemwas started.- Available inside the
Akka.HealthCheckNuGet package.
- Available inside the
DefaultLivenessProvider- The default liveness probe. The probe reports the time theActorSystemwas started.- Available inside the
Akka.HealthCheckNuGet package.
- Available inside the
ClusterReadinessProbeProvider- Readiness probe for clustering.- Reports unhealthy when:
- All other nodes in the cluster is unreachable.
- Available inside the
Akka.HealthCheck.ClusterNuGet package.
- Reports unhealthy when:
ClusterLivenessProbeProvider- Liveness probe for clustering.- Reports unhealthy when:
- The
ActorSystemleft the cluster.
- The
- Available inside the
Akka.HealthCheck.ClusterNuGet package.
- Reports unhealthy when:
AkkaPersistenceLivenessProbeProvider- Liveness probe for persistence. It probes the persistence storage every second to check that persistence is working properly.- Reports healthy when persistence successfully recover both journal and snapshot data from storage.
- Reports unhealthy when:
- Persistence just started and has not recovered.
- Either journal or snapshot failed recovery inside the periodic check.
- Available inside the
Akka.HealthCheck.PersistenceNuGet package.
To use the Akka.Hosting extension method, you will need to install the Akka.HealthCheck.Hosting package.
dotnet add package Akka.HealthCheck.HostingNOTE
Unlike the core library,
Akka.HealthCheck.Hostingalready includesAkka.HealthCheck.ClusterandAkka.HealthCheck.Persistenceas its dependency; there is no need to install these packages to start usingAkka.HealthCheckwith clustering or persistence.
To add health check to your actor system, use the .WithHealthCheck() hosting extension method:
using var host = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddAkka("test-system", (builder, provider) =>
{
// Add Akka.Cluster support
builder.WithClustering();
// Add persistence
builder
.WithInMemoryJournal()
.WithInMemorySnapshotStore();
// Add Akka.HealthCheck
builder.WithHealthCheck(options =>
{
// Here we're adding all of the built-in providers
options.AddProviders(HealthCheckType.All);
});
});
})
.Build();
await host.RunAsync();HealthCheckType is a bit flag enum that consists of these choices:
[Flags]
public enum HealthCheckType
{
DefaultLiveness = 1,
DefaultReadiness = 2,
Default = DefaultLiveness | DefaultReadiness,
ClusterLiveness = 4,
ClusterReadiness = 8,
Cluster = ClusterLiveness | ClusterReadiness,
PersistenceLiveness = 16,
Persistence = PersistenceLiveness,
All = Default | Cluster | Persistence
}To change the persistence liveness probe interval, configure the health check options:
// Add Akka.HealthCheck
builder.WithHealthCheck(options =>
{
options.AddProviders(HealthCheckType.All);
// change the persistence liveness probe interval to 5 seconds
options.Liveness.PersistenceProbeInterval = TimeSpan.FromSeconds(5);
});NOTE
The cluster and persistence probe providers for
Akka.HealthCheckare published in separate NuGet packages.
- If you need to use the cluster liveness and readiness probe, you need to install the
Akka.HealthCheck.ClusterNuGet package- If you need to use the persistence liveness probe, you need to install the
Akka.HealthCheck.PersistenceNuGet package
Akka.HealthCheck can be added manually through HOCON configuration:
var hocon = @"
akka.healthcheck {
log-config-on-start = on
log-info = on
liveness {
providers {
default = "Akka.HealthCheck.Liveness.DefaultLivenessProvider, Akka.HealthCheck"
cluster = "Akka.HealthCheck.Cluster.ClusterLivenessProbeProvider, Akka.HealthCheck.Cluster"
}
transport = tcp
tcp.port = 8080
}
readiness {
providers {
default = "Akka.HealthCheck.Readiness.DefaultReadinessProvider, Akka.HealthCheck"
custom = "MyAssembly.CustomReadinessProvider, MyAssembly"
}
transport = file
file.path = ""snapshot.txt""
}
}";
var config = ConfigurationFactory.ParseString(hocon);
var actorSystem = ActorSystem.Create("Probe", config);
var healthCheck = AkkaHealthCheck.For(actorSystem);
actorSystem.WhenTerminated.Wait();The full reference HOCON configuration are:
############################################
# Akka.HealthCheck Reference Config File #
############################################
akka.healthcheck{
# Log the complete configuration at INFO level when the actor system is started.
# This is useful when you are uncertain of what configuration is used.
log-config-on-start = on
# Log Liveness and Readiness probe event messages
# Such as Liveness/Readiness subscriptions, and status request
log-info = on
liveness {
# List of liveness probe providers.
# Custom end-user provider can be created by implementing the IProbeProvider interface.
providers {
# The default IProbeProvider implementation used for executing
# liveness checks inside Akka.HealthCheck
default = "Akka.HealthCheck.Liveness.DefaultLivenessProvider, Akka.HealthCheck"
# Clustering liveness check provider.
# To use, install the Akka.HealthCheck.Cluster NuGet package and uncomment this line.
#
#cluster = "Akka.HealthCheck.Cluster.ClusterLivenessProbeProvider, Akka.HealthCheck.Cluster"
# Persistence liveness check provider.
# To use, install the Akka.HealthCheck.Persistence NuGet package and uncomment this line.
#
#persistence = "Akka.HealthCheck.Persistence.AkkaPersistenceLivenessProbeProvider, Akka.HealthCheck.Persistence"
}
# Defines the interval for each persistence health check probe refresh
persistence.probe-interval = 10s
# Defines the signaling mechanism used to communicate with K8s, AWS, Azure,
# or whatever the hosting environment is for the Akka.NET application. The
# accepted values are 'file', 'tcp', and 'custom'.
#
# In the event of a custom transport (which is the default), Akka.HealthCheck
# won't try to automatically report any probe data to any medium. It's up
# to the end-user to query that data directly from the AkkaHealthCheck
# ActorSystem extension.
transport = custom
# If the `transport` used is `file`, this is where we specify the path of the file
# that we will write status data to. It's strongly recommended that you use an
# absolute path for best results.
file.path = "liveness.txt"
# If the `transport` used is `tcp`, this is where we specify the port # of the inbound
# socket that we're going open in order to accept external healthcheck connections.
tcp.port = 11000
}
readiness{
providers {
# The default IProbeProvider implementation used for executing
# readiness checks inside Akka.Healtcheck. Can be overridden by
# end-users via a custom IProbeProvider implementation.
default = "Akka.HealthCheck.Readiness.DefaultReadinessProvider, Akka.HealthCheck"
# Clustering readiness check provider.
# To use, install the Akka.HealthCheck.Cluster NuGet package and uncomment this line.
#
#cluster = "Akka.HealthCheck.Cluster.ClusterReadinessProbeProvider, Akka.HealthCheck.Cluster"
}
# Defines the signaling mechanism used to communicate with K8s, AWS, Azure,
# or whatever the hosting environment is for the Akka.NET application. The
# accepted values are 'file', 'tcp', and 'custom'.
#
# In the event of a custom transport (which is the default), Akka.HealthCheck
# won't try to automatically report any probe data to any medium. It's up
# to the end-user to query that data directly from the AkkaHealthCheck
# ActorSystem extension.
transport = custom
# If the `transport` used is `file`, this is where we specify the path of the file
# that we will write status data to. It's strongly recommended that you use an
# absolute path for best results.
file.path = "readiness.txt"
# If the `transport` used is `tcp`, this is where we specify the port # of the inbound
# socket that we're going open in order to accept external healthcheck connections.
tcp.port = 11001
}
}Akka.HealthCheck and Akka.Hosting can be directly integrated with Microsoft.AspNetCore.Diagnostics.HealthChecks, allowing users to access Akka.HealthCheck via HTTP REST API.
The package provides 5 IHealthCheck probes that can be registered with the health check middleware, each uniquely tagged so they can be individually filtered during mapping:
-
AkkaReadinessProbe- The default readiness probe. The probe reports the time theActorSystemwas started.Tags: [ "akka", "ready", "node" ]
-
AkkaLivenessProbe- The default liveness probe. The probe reports the time theActorSystemwas started.Tags: [ "akka", "live", "node" ]
-
AkkaClusterReadinessProbe- Readiness probe for clustering.- Reports healthy when:
- The
ActorSystemjoined a cluster. - The
ActorSystemis connected to a cluster
- The
- Reports unhealthy when:
- The
ActorSystemjust started has not joined a cluster. - All other nodes in the cluster is unreachable.
- The
Tags: [ "akka", "ready", "cluster" ]
- Reports healthy when:
-
AkkaClusterLivenessProbe- Liveness probe for clustering.- Reports healthy when:
- The
ActorSystemjoined a cluster. - The
ActorSystemis connected to a cluster
- The
- Reports unhealthy when:
- The
ActorSystemjust started and has not joined a cluster. - The
ActorSystemleft the cluster.
- The
Tags: [ "akka", "live", "cluster" ]
- Reports healthy when:
-
AkkaPersistenceLivenessProbe- Liveness probe for persistence. It probes the persistence storage every second to check that persistence is working properly.- Reports healthy when persistence successfully recover both journal and snapshot data from storage.
- Reports unhealthy when:
- Persistence just started and has not recovered.
- Either journal or snapshot failed recovery inside the periodic check.
Tags: [ "akka", "live", "persistence" ]
To integrate Akka.HealthCheck with ASP.NET, you will need to install the Akka.HealthCheck.Hosting.Web package.
dotnet add package Akka.HealthCheck.Hosting.WebThere are 3 steps that needs to be done to integrate Akka.HealthCheck with diagnostic health check
- Register health check probes to the health check middleware service.
- Add
Akka.HealthCheckto theActorSystem. - Map the health check probe routes.
The convenience IServiceCollection extension method WithAkkaHealthCheck(HealthCheckType) can be used to register the standard probes in any combination.
var webBuilder = WebApplication.CreateBuilder(args);
webBuilder.Services
.WithAkkaHealthCheck(HealthCheckType.All);As alternative, individual probes can be registered using these methods:
WithAkkaLivenessProbe()WithAkkaReadinessProbe()WithAkkaClusterLivenessProbe()WithAkkaClusterReadinessProbe()WithAkkaPersistenceLivenessProbe()
The convenience AkkaConfigurationBuilder extension method WithWebHealthCheck(IServiceProvider) automatically scans for any registered probes inside the health check middleware and adds the respective Akka.NET health check probes to the ActorSystem
var webBuilder = WebApplication.CreateBuilder(args);
webBuilder.Services
.WithAkkaHealthCheck(HealthCheckType.All)
.AddAkka("actor-system", (builder, serviceProvider) =>
{
// Automatically detects which health checks were registered
// inside the health check middleware and starts them
builder.WithWebHealthCheck(serviceProvider);
});The convenience IEndpointRouteBuilder extension method MapAkkaHealthCheckRoutes automatically scans for any registered probes inside the health check middleware and maps all the probes to a HTTP route. The HTTP route is the concatenation of the probe tags. By default:
AkkaReadinessProbeis mapped to "/healthz/akka/ready/node"AkkaLivenessProbeis mapped to "/healthz/akka/live/node"AkkaClusterReadinessProbeis mapped to "/healthz/akka/ready/cluster"AkkaClusterLivenessProbeis mapped to "/healthz/akka/live/cluster"AkkaPersistenceLivenessProbeis mapped to "/healthz/akka/live/persistence"- All liveness probes can be queried all at once at "/healthz/akka/live"
- All readiness probes can be queried all at once at "/healthz/akka/ready"
- All Akka.NET probes can be queried all at once at "/healthz/akka"
var webBuilder = WebApplication.CreateBuilder(args);
webBuilder.Services
// Register all of the health check service with IServiceCollection
.WithAkkaHealthCheck(HealthCheckType.All)
.AddAkka("actor-system", (builder, serviceProvider) =>
{
builder
// Automatically detects which health checks were registered
// inside the health check middleware and starts them
.WithWebHealthCheck(serviceProvider);
});
var app = webBuilder.Build();
// Automatically detects which health checks were registered inside
// the health check middleware and maps their routes
app.MapAkkaHealthCheckRoutes();
await app.RunAsync();By default, the health check middleware outputs a simple string response of either "healthy" or "unhealthy" regardless of the number of probes being queried. To more verbose response can be gained by using Helper.JsonResponseWriter as the route endpoint response writer.
app.MapAkkaHealthCheckRoutes(
optionConfigure: (_, opt) =>
{
// Use a custom response writer to output a json of all reported statuses
opt.ResponseWriter = Helper.JsonResponseWriter;
});Example output when all probes are enabled:
{
"status": "Healthy",
"results": {
"akka-live-node": {
"status": "Healthy",
"description": "Akka.NET node is alive",
"data": {
"message": "Live: 12/16/2022 9:54:28 PM +00:00"
}
},
"akka-ready-node": {
"status": "Healthy",
"description": "Akka.NET node is ready",
"data": {
"message": "Live: 12/16/2022 9:54:28 PM +00:00"
}
},
"akka-live-cluster": {
"status": "Healthy",
"description": "Akka.NET cluster is alive",
"data": {
"message": ""
}
},
"akka-ready-cluster": {
"status": "Healthy",
"description": "Akka.NET cluster is ready",
"data": {
"message": ""
}
},
"akka-live-persistence": {
"status": "Healthy",
"description": "Akka.NET persistence is alive",
"data": {
"message": "RecoveryStatus(JournalRecovered=True, SnapshotRecovered=True)"
}
}
}
}To manually setup a custom IProbeProvider, check the custom probe example project.
Documentation on how to set up ASP.NET Core health check can be read here
To run the build script associated with this solution, execute the following:
Windows
c:\> build.cmd all
Linux / OS X
c:\> build.sh all
If you need any information on the supported commands, please execute the build.[cmd|sh] help command.
This build script is powered by FAKE; please see their API documentation should you need to make any changes to the build.fsx file.
The attached build script will automatically do the following based on the conventions of the project names added to this project:
- Any project name ending with
.Testswill automatically be treated as a XUnit2 project and will be included during the test stages of this build script; - Any project name ending with
.Testswill automatically be treated as a NBench project and will be included during the test stages of this build script; and - Any project meeting neither of these conventions will be treated as a NuGet packaging target and its
.nupkgfile will automatically be placed in thebin\nugetfolder upon running thebuild.[cmd|sh] allcommand.
This solution also supports DocFx for generating both API documentation and articles to describe the behavior, output, and usages of your project.
All of the relevant articles you wish to write should be added to the /docs/articles/ folder and any API documentation you might need will also appear there.
All of the documentation will be statically generated and the output will be placed in the /docs/_site/ folder.
To preview the documentation for this project, execute the following command at the root of this folder:
C:\> serve-docs.cmd
This will use the built-in docfx.console binary that is installed as part of the NuGet restore process from executing any of the usual build.cmd or build.sh steps to preview the fully-rendered documentation. For best results, do this immediately after calling build.cmd buildRelease.
This project will automatically populate its release notes in all of its modules via the entries written inside RELEASE_NOTES.md and will automatically update the versions of all assemblies and NuGet packages via the metadata included inside Directory.Build.props.
All new projects added into the solution will automatically picks up all the settings set inside Directory.Build.props.
This project uses SignService to code-sign NuGet packages prior to publication. The build.cmd and build.sh scripts will automatically download the SignClient needed to execute code signing locally on the build agent, but it's still your responsibility to set up the SignService server per the instructions at the linked repository.
Once you've gone through the ropes of setting up a code-signing server, you'll need to set a few configuration options in your project in order to use the SignClient:
- Add your Active Directory settings to
appsettings.jsonand - Pass in your signature information to the
signingName,signingDescription, andsigningUrlvalues insidebuild.fsx.
Whenever you're ready to run code-signing on the NuGet packages published by build.fsx, execute the following command:
C:\> build.cmd nuget SignClientSecret={your secret} SignClientUser={your username}
This will invoke the SignClient and actually execute code signing against your .nupkg files prior to NuGet publication.
If one of these two values isn't provided, the code signing stage will skip itself and simply produce unsigned NuGet code packages.