Monitor third-party systems with custom checks

Component: ServiceControl CustomChecks
NuGet Package NServiceBus.CustomChecks (3.x)
Target NServiceBus Version: 7.x

External, third-party systems becoming unavailable might cause messages processing failures. The Particular Platform supports monitoring of third-party systems exposed as HTTP endpoints. This sample shows how to set up such monitoring using custom checks.

This sample includes a portable version of the Particular Service Platform tools. These tools are only availabe on Windows environments but are not necessary to run run the sample.

Running the sample

Running the project will result in 3 console windows:

  1. Samples.CustomChecks.3rdPartySystem: Represents the 3rd party system by simulating an HTTP service running on http://localhost:57789. At startup, the custom check is returning success, but the state can be toggled between success and failure by pressing Enter.
  2. Samples.CustomChecks.Monitor3rdParty: The endpoint containing the custom check. The success or failure of the 3rd-party system is continuously written to the console.
  3. PlatformLauncher: Runs an in-process version of ServiceControl and ServicePulse. When the ServiceControl instance is ready, a browser window will be launched displaying the Custom Checks view in ServicePulse.

Try toggling the status of the third-party system by pressing Enter in the Samples.CustomChecks.3rdPartySystem window, and watch the change in the output of the Samples.CustomChecks.Monitor3rdParty window.

The status of the custom check is also reported to ServiceControl, and can be viewed in ServicePulse. In the browser window, navigate to the ServicePulse Custom Checks page to see the status change from success to error. The ServicePulse Dashboard page provides the overall status of custom checks.

The custom check

The monitoring logic implements a PeriodicCheck which calls a configured URI whenever specified interval elapses. When the third-party system doesn't respond in a timely fashion a CheckResult.Failed event is sent to ServiceControl.

class ThirdPartyMonitor :
    CustomCheck
{
    const string url = "http://localhost:57789";
    static ILog log = LogManager.GetLogger<ThirdPartyMonitor>();
    static HttpClient client = new HttpClient { Timeout = TimeSpan.FromSeconds(3) };

    public ThirdPartyMonitor()
        : base(
            id: $"Monitor {url}",
            category: "Monitor 3rd Party ",
            repeatAfter: TimeSpan.FromSeconds(10))
    {
    }

    public override async Task<CheckResult> PerformCheck()
    {
        try
        {
            using (var response = await client.GetAsync(url)
                .ConfigureAwait(false))
            {
                if (response.IsSuccessStatusCode)
                {
                    log.Info($"Succeeded in contacting {url}");
                    return CheckResult.Pass;
                }
                var error = $"Failed to contact '{url}'. HttpStatusCode: {response.StatusCode}";
                log.Info(error);
                return CheckResult.Failed(error);
            }
        }
        catch (Exception exception)
        {
            var error = $"Failed to contact '{url}'. Error: {exception.Message}";
            log.Info(error);
            return CheckResult.Failed(error);
        }
    }
}

Related Articles


Last modified