How I monitor my VPS for free!

Home made server monitoring with SMS alerts.

Categories: Archived, Development

As I have moved over to a VPS server in the past 6 months I have run up against the paranoia of “is my server still running?”

I had been using pingdom.com, a great service that pings a site every couple of minutes and notifies you of an outage. This was great when I was on a shared server and could more or less rely on things booting back up. Since I moved to a VPS where everything is my own problem I learned that it won’t help if there is a DNS issue or even a Database issue. The site has to return a 404.

I started looking into other solutions such as statuspage.io ( back when they had a free account, they have since removed that plan ) but it required some javascript on your error pages. This meant that your visitors would trigger the necessary outage message. Something I didn’t want to have happened and probably would not have let me know of the issue until it was a problem.

So I set out to find a solution.

The Goal

  • Monitor any DNS issue and make sure the status of 200 is returned
  • Make sure that a connection to MySQL can be made
  • Make sure that a domain returns a status of 200 is returned

The Tools

Since Pingdom already does an excellent job pinging my site I knew that I could rely on it to keep up the good work.

I get a ping every 5 min using the free plan.

Pingdom will send you an email when your site is down but again they won’t help for any Apache or MySQL issues.

So I chose to use Twillio, as their free account would send text messages ( you should be paying for this… ).

I hosted the script on my VPS because I don’t allow outside MySQL connections and I had no reason to open one up. Remember, Pingdom will email me if everything goes pear-shaped.

Execution

Let’s start by checking the DNS: using dns_get_record(), It is important to note that the domain did not contain the protocol or the subdomain ( www ).

$url = 'tentaclecms.com';
$dns = dns_get_record($url);

if ($dns == null) {

    $data['dns']['success'] = 'false';
    $data['dns']['message'] = 'Problem connecting to the DNS. ';
    $data['dns']['status'] = 'red';
}
else {
    $data['dns']['success'] = 'true';
    $data['dns']['message'] = 'The DNS is good. ';
    $data['dns']['status'] = 'green';
}

Next, let’s make sure we can make a connection to the database:

$host = 'localhost';
$username = 'root';
$password = '';
$driver = 'mysql';
$table = 'table_name';

try {
    $pdo = new pdo( $driver.':host='.$host.';dbname='.$table.'',
        $username,
        $password,
        array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

    $data['mysql']['success'] = 'true';
    $data['mysql']['message'] = 'The database connection is good. ';
    $data['mysql']['status'] = 'green';
}
catch(PDOException $ex){
    $data['mysql']['success'] = 'false';
    $data['mysql']['message'] = 'Problem connecting to the database. ';
    $data['mysql']['status'] = 'red';
}

Checking the response headers:

function get_contents($url) {
    $http_response_header = '';
    @file_get_contents($url);

    return $http_response_header;
}

$server = get_contents('http://www.'.$url);

if (is_array($server)) {
    if (strpos($server[0], '200'))
    {
        $data['server']['success'] = 'true';
        $data['server']['message'] = 'OK, The page loaded correctly. ';
        $data['server']['status'] = 'green';
    } elseif (strpos($server[0], '404'))
    {
        $data['server']['success'] = 'true';
        $data['server']['message'] = 'The page is missing. ';
        $data['server']['status'] = 'yellow';
    } elseif (strpos($server[0], '500'))
    {
        $data['server']['success'] = 'false';
        $data['server']['message'] = 'There is an internal server error. ';
        $data['server']['status'] = 'red';
    } 

} else {
    $data['server']['success'] = 'false';
    $data['server']['message'] = 'Not sure whats wrong, the URL is missing. ';
    $data['server']['status'] = 'red';
}

Let’s do something with our Array.

From this point, I can now loop through the $data array to see if anything failed.

Have a look at the Twillio example, Download and include the “Services/Twilio.php”. When we come across an error with our site we can trigger an SMS message to notify us of the problem. If the site its self is totally unreachable Pingdom will let us know.

Make a function called sms http://www.twilio.com/docs/quickstart/php/sms/sending-via-rest

function sms ( $message ) {
    require "Services/Twilio.php";

    $AccountSid = "";
    $AuthToken = "";

    $client = new Services_Twilio($AccountSid, $AuthToken);

    $people = array( "+yournumber" => "Your Name" );

    foreach ($people as $number => $name) {
        $sms = $client->account->sms_messages->create(
            "twillionumber", 
            $number,
            $message
        );
    }   
}

When we hit a problem we can pass the $data[‘server’][‘message’] to sms().

If SMS is not your thing then send an email.

function alert( $message ) {
    mail([email protected] ', 'Subject', $message);
}

Done!


Adam Patterson

Adam Patterson

User Interface Designer & Developer with a background in UX. I have spent 5 years as a professionally certified bicycle mechanic and ride year-round.

I am a husband and father of two, I enjoy photography, music, movies, coffee, and good food.

You can find me on Twitter, Instagram, and YouTube!