How to Setup ASP.NET Core Health Check UI

Published on 10 September 2020

In Part one we setup the health check endpoints, now to add a frontend.

The Health Checks UI is best hosted in its own service as it can consolidate health checks for a number of services.

Swagger CORS error

Adding the HealthChecks UI to the service involves adding 2 nuget packages, the main AspNetCore.HealthChecks.UI package and a storage provider, initially I have used the InMemory storage provider as I do not have the need to see historical data. There are also providers various databases including SqlServer and SQLite which can be used to persist the data.

    <PackageReference Include="AspNetCore.HealthChecks.UI" Version="$(AspNetCoreHealthChecksUIVersion)" />
    <PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="$(AspNetCoreHealthChecksUIVersion)" />

As the HealthChecks nuget packages will be used across all projects I have set the version numbers centrally in Directory.Build.props.

<AspNetCoreHealthChecksUIVersion>3.1.1</AspNetCoreHealthChecksUIVersion>

The HealthChecks UI can now be added to ConfigureServices and Configure in Startup.cs.

As I want to limit the access to the UI in the same way as I did for the HealthCheck endpoints I have the service listening on multiple ports and use RequireHost when configuring the endpoints to ensure the UI is only accessible internally.

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddHealthChecksUI()
        .AddInMemoryStorage();
    services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHealthChecksUI();
    
    app.UseEndpoints(endpoints =>
        
    {
        endpoints.MapControllers();
        endpoints.MapHealthChecksUI(config => {
            config.UIPath = "/hc-ui";
            }).RequireHost($"*:{Configuration["ManagementPort"]}");
        });
    }
}

Finally we need to tell the UI where to read the HealthChecks from, this can either be done in a configuration file

...
  "https_port": 1131,
  "Urls": "http://localhost:1130;https://localhost:1131;https://localhost:1132",
  "ManagementPort": "1132",
  "AllowedHosts": "*",
  "HealthChecks-UI": {
    "HealthChecks": [
      {
        "Name": "LoginService Check",
        "Uri": "https://localhost:1116/hc"
      },
      {
        "Name": "ResourceService Check",
        "Uri": "https://localhost:5002/hc"
      },
      {
        "Name": "NotificationService Check",
        "Uri": "https://localhost:1179/hc"
      }
    ]
  }
...

or in code by adding settings to the AddHealthChecksUI method.

services.AddHealthChecksUI(setupSettings: settings =>
                    {
                        settings
                            .DisableDatabaseMigrations()
                            .AddHealthCheckEndpoint(name: healthCheckName, uri: healthCheckUri)
                            .AddWebhookNotification(name: webhookName, uri: webhookUri, payload: webhookPayload,
                                restorePayload: webhookRestorePayload)
                            .SetEvaluationTimeInSeconds(evaluationTimeInSeconds)
                            .SetMinimumSecondsBetweenFailureNotifications(minimumSeconds);
                    }).AddInMemoryStorage();

You can get the full working demo from my GitHub repo.