Runscope API Testing and Monitoring    Learn More →

Build a Health Check API for Services Underneath Your API

By Neil Mansilla on .

A running cat, in honor of National Cat Day. That's Oskar (click photo for original). Full attribution below.

running cat, in honor of National Cat Day. That's Oskar (click photo for original). Full attribution below.

Monitoring your API's health and performance is something Runscope can do very well. But what about monitoring the underlying services that your API relies on? Databases, like MySQL and Redis, or DNS services on BIND or Mara -- they don't come with RESTful APIs, and in fact, they communicate over lower-level protocols like TCP and UDP. 

When you're relying on services without monitoring, the only time you realize those services are down is when your API (or the apps that rely on your API) go down. Wouldn't it be great if those services had health check API endpoints?

Creating separate health check API endpoints for all services

One approach is to build simple health check API endpoints — a method similar to a ping that reports whether the service is up or down.  Consider building a health check endpoint for every service your backend relies on and using Runscope for testing, reporting and triggering notifications. If you use the same client library or SDK in the health check app that you use for your API backend, you'll have the additional benefit of dependency testing that client library.

That being said, include as few dependencies as possible, isolating the health check app to only what's necessary to connect to the service. I mean, you wouldn’t want a MySQL test to fail because Redis was down. The health check endpoint should do one thing, and one thing only — check that a single service is up and running. If so, return 200. If not, return 503.

MySQL service check example

Below is a pint-sized PHP sample app to test if a MySQL server is up. This app has no library dependencies. It's using PHP's integrated mysqli library. This app can be parked on any web server that can execute/interpret PHP files (e.g. Apache, Nginx, etc.). Ideally, it would be mapped to an endpoint route specifically for health check resources -- but in this example, I've just placed it in the home directory of a vanilla Apache instance. I have MySQL running on another box located on the local network (10.0.1.150) and bound to the default port (3306).

<?php
  $config = [
     "server"     => “10.0.0.150:3306",
     "username"   => "runscope",
     "password"   => "testpass"
  ];
  header('Content-type: application/json');

  $link = new mysqli($config['server'],$config['username'],$config['password']);

  if ($link->connect_errno) {
    http_response_code(503);
    echo('{ "status": "Unable to connect" }');
  }
  else {
    http_response_code(200);
    echo('{ "status": "Connection successful." }');
  }
?>

Ping! Test the endpoint with Runscope Radar Agent

Since my MySQL and Apache servers are behind the firewall, I'll be testing my new health check endpoint with Runscope Radar Agent. This agent will perform tests on the local network and report the results back to Runscope. The only requirement when using the remote Radar Agent is that the computer can make HTTPS requests. Read more about (and download) the Runscope Radar Agent here

After I ran the agent on my local machine (took only a minute to set up), it appeared as a testing location on my Runscope Radar test editor. The location titled Internal-SFO-Office in the screenshot below is my laptop that's running the Runscope Radara Agent.

Runscope Radar Test Editor view. After installing the Runscope Radar Agent on my local machine, it pops up in the list of testing locations.

Runscope Radar Test Editor view. After installing the Runscope Radar Agent on my local machine, it pops up in the list of testing locations.

Next, I clicked Run Now. The MySQL health check test ran from my local Radar Agent. Below were the results from Traffic Inspector.

Setting up notifications

Viola! The next step would be adding notifications, so that if there is a failure, the correct individual or team could receive email notifications. Additionally, Runscope supports webhooks, so that after tests run, succeed, or fail, Runscope can POST the test result data to any URL. Lastly, if you use PagerDuty, HipChat, Slack, Zapier, etc., Runscope smoothly integrates with all of those services. Read more about notifications here.

Should these be public or private?

You might ask yourself whether these endpoints should be made public or private. The short answer is private. By private, I mean that these should be treated as internal to your company, and not shared with partners or third party consumers of your API. Why? Because the information is too granular and could reveal details about your infrastructure that shouldn't be made public. However, if you were to wrap up all of these micro health checks together, and return a more abstract status response, that would be appropriate as a publicly accessible endpoint.

More micro sample health check apps on GitHub

In addition to the PHP+MySQL sample above, we've built a couple of other examples: Python+Redis, .Net/C#+MS-SQL and Perl+DNS. You're more than welcome to contribute your own. The GitHub repo is located here.

If you need some tips on how to get these health check apps working, or help with setting up Runscope Radar tests against them, our support team is standing by, happy to help.

p.s. I'll be following up with a blog post about a more comprehensive, open source, service health check project that's being worked on here at Runscope.

Cat photo attribution:  LInk to original photo here (Flickr user Tambako). Used under Creative Common license.

Categories: code samples, howto, apis, testing, monitoring

Everything is going to be 200 OK®