All Articles

Service Fabric app health check

Health check is a common pattern in cloud native applications, especially in Kubernetes services. Service Fabric supports health check. When you deploy a new version to a cluster, you can set up the pipeline so that if the health is bad, the deployment fail.

Add health check libraries


Register the service against IHealthCheck interface

// Startup.cs
public void ConfigureServices(IServiceCollection services)
    services.AddTransient<IEnumerable<IHealthCheck>>(x =>
        var cosmosDbOptions = x.GetService<IOptions<CosmosDbOptions>>().Value;

        return new List<IHealthCheck>{new CosmosDbHealthCheck(cosmosDbOptions.ConnectionString)};


Add an healthcheck endpoint

// Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    app.UseEndpoints(x => x.MapHealthChecks("/health"));

As we registered CosmosDb healthcheck in the services collection, the cosmos db healtcheck will be carried out when this endpoint gets called.

// ConfigureServices

Also we want to carry out a regular health check and report the status back to Service Fabric cluster. So override RunAsync from Api class

// Api.cs
protected override async Task RunAsync(CancellationToken cancellationToken)
    var configBuilder = new ConfigurationBuilder();

    configBuilder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
    configBuilder.AddJsonFile($"appsettings.Development.json", true);
    var config = configBuilder.Build();

    var results = new List<HealthCheckResult>();
    var healthchecks = new List<IHealthCheck>
        new CosmosDbHealthCheck(config.GetSection("CosmosDb:ConnectionString").Value)

    var intervalSuccess = TimeSpan.FromMinutes(30);
    var intervalFailure = TimeSpan.FromMinutes(1);

    while (!cancellationToken.IsCancellationRequested)
        foreach (var healthcheck in healthchecks)
            var name = healthcheck.GetType().Name;
            var context = new HealthCheckContext()
                Registration = new HealthCheckRegistration(name,
                    new string[] { }
            var result = await healthcheck.CheckHealthAsync(context);
            Partition.ReportInstanceHealth(new HealthInformation("ServiceHealthCheck", 
                Description = result.Exception != null
                    ? $"{result.Exception.GetType().Name} : {result.Exception.Message}"
                    : result.Description ?? string.Empty


        var interval = results.Any(x => x.Status != HealthStatus.Healthy) 
            ? intervalFailure 
            : intervalSuccess;

        await Task.Delay(interval);


public static HealthState Convert(HealthStatus status)
    switch (status)
        case HealthStatus.Degraded:
            return HealthState.Warning;
        case HealthStatus.Healthy:
            return HealthState.Ok;
        case HealthStatus.Unhealthy:
            return HealthState.Error;
            return HealthState.Unknown;