2

I am using .NET Core 3.1 to develop a web application. It depends on several other external services (APIs written in Node.js). I would like to monitor the health of external services and use HealthChecks.UI to show the health on a separate page. I am not interested in health of my own application, I am interested about the health of the dependent external systems. Can this be achieved by health checks package?

This is the code that I have currently:

Startup.cs

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddHealthChecks()
            .AddCheck<ExternalServiceHealthCheck>("External service health check");
        
        services
            .AddHealthChecksUI()
            .AddInMemoryStorage();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseStaticFiles();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHealthChecksUI(setup =>
            {
                setup.UIPath = "/HealthChecks";
            });
        });
    }
}

ExternalServiceHealthCheck.cs

public class ExternalServiceHealthCheck : IHealthCheck
{
    public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        return Task.FromResult(HealthCheckResult.Healthy("External service is healthy"));
    }
}

When I go to /HealthChecks, I get an empty UI even though I registered ExternalServiceHealthCheck (see image). Why is it not showing on /HealthChecks page?

enter image description here

Sam Carlson
  • 1,891
  • 1
  • 17
  • 44
  • There is description [how to add a custom healthcheck](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks?view=aspnetcore-3.1#create-health-checks-1) in the document you have linked. – Guru Stron Jul 02 '21 at 09:56
  • I added a custom health check but it is still not showing on the UI. Check edited question. – Sam Carlson Jul 02 '21 at 10:00
  • Do you want to display the page of another system or do you want to check the availability of another system and display the health check page? – FatTiger Jul 02 '21 at 10:06
  • The second option. I want to display an UI in my application which would display the health check status of all external APIs. – Sam Carlson Jul 02 '21 at 10:07
  • Did you add app.UseStaticFiles(); ? Check if the browser console outputs 404 – FatTiger Jul 02 '21 at 10:14
  • Yes, I have `app.UseStaticFiles()`. Browser doesn't output 404 when I go to `/HealthChecks`. It displays the UI correctly, but the health check isn't listed there (see edited question with image). – Sam Carlson Jul 02 '21 at 10:17

2 Answers2

1

It looks like the UI cannot see the healthchecks. By default, unless you have configured it otherwise, the UI looks for /healthchecks-api to get the data for what healthchecks to render.

Also the /healthchecks-api needs to install the AspNetCore.HealthChecks.UI.Client package and set that packages UIResponseWriter as the ResponseWriter property of the options:

app.MapHealthChecks("/healthchecks-api", new HealthCheckOptions
{
    Predicate = _ => true,
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});

You should be able to view /healthchecks-api and see some JSON coming back, rather than the basic "healthy"/"unhealthy" message. This is all from the readme for the HealthChecks UI package.

Fermin
  • 34,961
  • 21
  • 83
  • 129
  • This is the code that I have [currently](https://pasteboard.co/K9ik31S.png). However, when I go to `/healthchecks-api`, I get the following exception: `AmbiguousMatchException: The request matched multiple endpoints. Matches: HealthChecks UI Api, Health checks`. – Sam Carlson Jul 02 '21 at 10:46
  • I created a very simple project where you can reproduce the issue. It is available here: http://www.filedropper.com/healthchecktest – Sam Carlson Jul 02 '21 at 11:16
0

I fully reproduced your problem locally, when I added in the configuration file

"HealthChecks-UI": {
     "HealthChecks": [
       {
         "Name": "Ordering HTTP Check",
         "Uri": "http://localhost:5102/hc"
       },
       {
         "Name": "Ordering HTTP Background Check",
         "Uri": "http://localhost:5111/hc"
       }
     ]
   }

It can display correctly.

If you want to use healthchecks-ui, you must configure the Endpoint through the appsettings.json or in the Startup, otherwise it cannot be displayed on the UI. In your case, as long as the API Endpoint returns http status code 200, it is the health status. So you should provide APIs specifically for Health Check in other projects. If everything is normal, they only need to return http status code 200.

FatTiger
  • 647
  • 5
  • 14
  • 1
    These `Uri` fields should point at external services, right (ex. `https://api.external.com/GetServiceInfo`)? External services that I use are written in Node.js, they don't have standard .NET Core health check output. I want to write custom logic for determining their health, ex. calling one of their URLs and parsing the JSON result. – Sam Carlson Jul 02 '21 at 10:52