3

The question is just as asked on the title. It is simple to perform a check for the database operations, queries, commands and event store but I am clueless as to how/what is the best way to perform a health check on a hostedservice. Could anyone advice?

Nicholas
  • 1,883
  • 21
  • 39
  • Does [this](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks?view=aspnetcore-3.1) answer your question ? You need to configure specific endpoint in your application which then can be used for performing healthcheck probes by kubernetes. – mario Feb 28 '20 at 11:46
  • @mario Nope! haha, i wish it was tho, I specifically want a HostedService to be checked for its health, i.e. its memory usage (if possible) or at least whether if it is still functioning properly or not. – Nicholas Feb 29 '20 at 17:35
  • @ Nicholas, so unfortunatelly I won't be able to help you this time. ;) I couldn't find anything about performing health checks specifically on a hosted service either. Good luck! – mario Feb 29 '20 at 18:06

3 Answers3

7

Additionally from Simon B, this official Microsoft documentation has drafted out a complete guide to writing a health check structure for your Hosted services.

You need 3 elements:

  1. The HealthCheck class for your hosted service
  2. The HealthCheck Provider DI, along with the HealthCheck class' DI.
  3. A HealthCheck publisher
Nicholas
  • 1,883
  • 21
  • 39
6

The IHostedService interface (and BackgroundService base implementation) has overridable methods StartAsync() and StopAsync(). In our background service we have:

public override Task StopAsync(CancellationToken cancellationToken)
{
      _logger.LogWarning("Background service stopping");
      return Task.CompletedTask;
}

You could use this to run whatever you want to notify in some way when your HostedService starts or stops.

If you need to have a way of polling the service, you could perhaps inject a singleton that has a simple status within it, that is set by these methods. Then, a health check controller on your API / website could also have that injected and read the status of the singleton. Something like this:

    public interface IHostedServiceStatus
    {
        bool IsHostedServiceRunning { get; set; }
    }

    public class HostedServiceStatus : IHostedServiceStatus
    {
        public bool IsHostedServiceRunning { get; set; }
    }

Set that up as a singleton, inject into your HostedService and set IsHostedServiceRunning on the StartAsync() and StopAsync() methods appropriately. Then also inject into your health check controller and read IsHostedServiceRunning.

Simon B
  • 976
  • 1
  • 11
  • 20
0

Another option is to use the ExecuteTask property of the BackgroundService class:

/// <summary>
/// Gets the Task that executes the background operation.
/// </summary>
/// <remarks>
/// Will return <see langword="null"/> if the background operation hasn't started.
/// </remarks>
public virtual Task? ExecuteTask => _executeTask;

Using this you can derive the status of the background service as follows:

@if (service.ExecuteTask == null)
{
    // Status = "Loading"
}
else
{
    if(!service.ExecuteTask.IsCompleted)
    {
        // Status = "Running"
    }
    else
    {
        // Status = "Stopped"
    }
}

Alternatively you could even use the task's TaskStatus

Christiaan Wevers
  • 422
  • 1
  • 6
  • 12