Early alerting: Monitoring an API with a heartbeat cron

Sometimes, when your site has a deep interaction with a remote API because of business logic, you need a way to rapidly be noticed if something goes wrong with communication to start contingency actions that avoid users to have a bad experience.

Couple month ago I found myself creating a simple but useful solution for a client.

Brief story

Our client’s API is overall reliable, but none are free of unforeseen events like internet outages, database didn’t up properly after backups, server shutdown and so on.

Those are a problem when your app needs to connect from the very beginning, Login.
The sooner one get noticed, the sooner can find the fix and eventually fix it.

Solution

Since I need to at least check if the Login is working, my first approach was create an script that emulate the request performed by the during the Login process. I’ve created a Command Line Interface (CLI) PHP script, that bootstrap Erdiko framework giving me the chance to use application’s models.

With this script, I was able to call the login endpoint with a valid test user, and parse the response looking for a success Login. Since I’m using a valid user, any response except success means API issue.

#!/usr/bin/php
<?php require_once (dirname(__FILE__).'./app/bootstrap.php'); try { $apiModel = new \app\models\ApiModel(); $result=false; $params = [ 'username' => 'test',
      'password' => 'Password!'
    ];
    $result = $apiModel->login( $params );
  	if(empty($result)){
  		throw new Exception("No Response from API");
    } else {
	    $result = (object)$result;
  		if ( ! empty( $result->error_code ) && ( $result->error_code != '0' ) ) {
  			$message = $result->error_code;
  			if ( property_exists( $result, 'error_detail' ) && !empty($result->error_detail)) {
  			    $message .= " - ".$result->error_detail;
        }
  			throw new Exception($message);
  		}
  	}
} catch (\Exception $e) {
    \Erdiko::log(\Psr\Log\LogLevel::ERROR, "API Heartbeat: " . $e->getMessage());
    $path = '/config/api';
    $config = \Erdiko::getConfig($path);
    $_config = $config['heartbeat'];

    $msg = "API Login Error: " . $e->getMessage();
    // send mail
    $mail = new \app\models\Mail('default');
    $to = $_config['to'];
    $from = $_config['from'];
    $subject = $_config['subject'];
    $result = $mail->send($to, $from,$subject, $msg, $msg);
    $sent = ($result) ? "yes" : "no";
    \Erdiko::log(\Psr\Log\LogLevel::ERROR, "API Heartbeat - email sent: " . $sent);
}

That was a good starting point, now I need to notify a group of people that something went wrong and needs to be handled. That was easy, I just send an email to a list of email addresses I get from a config file.

The last but not the least, how to make it a real alert process? Easy, execute the script in the OS cron, I added a task that runs each 5 minutes and send the notification.

Here’s an example on how to add to the cron:

$ crontab -e
*/5 * * * * php -f /var/www/scripts/api/api_heartbeat.php

Improvement

To make it more useful than just a “API is down…”, I’ve included in the script an error handling to identify and categorize them to give more details to the support team.

Conclusion

You can find a bunch of monitoring solutions that can help you monitoring your servers and services,  Data Dog is a nice example of that, it provides a variety of pre-built integration widgets that allows to to check if, different
kinds of services are up and running, also provides a flexible API that allows you to make some customizations. But if you need something that fit very custom specs or there’s no enough room in your budget, you will have to do it by yourself, I hope this example be useful as a guideline or at least a starting point. Thanks for reading and see you in next posts.

Next Post

Comments

See how we can help

Lets talk!

Stay up to date on the latest technologies

Join our mailing list, we promise not to spam.