asp.net-corekestrel-http-serverms-yarp

get health status and log it - YARP


I am working with YARP for reverse proxy to communicate with end points. I need to check the health status (like working properly, downtime, transient issues etc). I have followed the configurations mentioned in the following YARP documentation:

https://microsoft.github.io/reverse-proxy/articles/dests-health-checks.html#available-destination-collection

The configuration for health check in appsettings.json is:

"Clusters": {
      "abc": {
        "HealthCheck": {
          "Active": {
            "Enabled": "true",
            "Interval": "00:00:10",
            "Timeout": "00:00:10",
            "Policy": "ConsecutiveFailures",
            "Path": "/test"
          }
        },
        "Metadata": {
          "ConsecutiveFailuresHealthPolicy.Threshold": "3"
        },
        "Destinations": {
          "abc": {
            "Address": "http://localhost:5500/abc",
            "Health": "http://localhost:5500/"
          }
        }
      },
      "api": {
        "Destinations": {
          "api": {
            "Address": "http://localhost:5600/"
          }
        }
      }
    }

I am able to hit the action on 'abc' end point. However since I want to log the status, I had written the following class, following the sample in the above given link.

using Yarp.ReverseProxy.Health;
using Yarp.ReverseProxy.Model;

namespace YarpReverseProxyServer
{
    public class HealthResponsePolicy : IActiveHealthCheckPolicy
    {
        private readonly IDestinationHealthUpdater _healthUpdater;

        public HealthResponsePolicy(IDestinationHealthUpdater healthUpdater)
        {
            _healthUpdater = healthUpdater;
        }

        public string Name => "HealthResponsePolicy";

        public void ProbingCompleted(ClusterState cluster, IReadOnlyList<DestinationProbingResult> probingResults)
        {
            if (probingResults.Count == 0)
            {
                return;
            }

            var newHealthStates = new NewActiveDestinationHealth[probingResults.Count];
            for (var i = 0; i < probingResults.Count; i++)
            {
                var response = probingResults[i].Response;
                var newHealth = response is not null && response.IsSuccessStatusCode ? DestinationHealth.Healthy : DestinationHealth.Unhealthy;
                newHealthStates[i] = new NewActiveDestinationHealth(probingResults[i].Destination, newHealth);
            }

            _healthUpdater.SetActive(cluster, newHealthStates);
        }
    }
}

and then add the following line in Startup.cs, although it was not mentioned in the above link:

services.AddSingleton<IActiveHealthCheckPolicy, HealthResponsePolicy>();

However this does not work, because code never hits to ProbingCompleted method of HealthResponsePolicy class. I cant understand what I am missing.


Solution

  • I have found what was the problem. I had to set the following policy to the custom class HealthResponsePolicy in the appsettings.json under Clusters attribute.

    "Policy": "HealthResponsePolicy"