PHP script for server ping monitoring

I’ve been using a PHP script I wrote to monitor whether some of our servers are alive or dead using ping, and send an alarm email if there is no response from the server for a certain period of time. It wasn’t working properly, and today I finally fixed it.

The script can be run from the command line and allows you to define the ping target or destination (the server) you want to monitor, the name of the machine you are pinging from (useful if you’re pinging to and from a matrix of machines) and the email address you would like to send any alarm emails to. It seems to work well on a couple of Linux machines I tried it on.

You run the script using e.g. the following command:

/usr/bin/php /home/username/php-monitor/ping-host.php -h target.example.com -l pinger.example.com -e myaddress@example.com,+31628233133@sms.orange.nl

…where you need to put the path to the php package in your setup instead of “/usr/bin/php”, you need to put the path to the PHP script (I named it ping-host.php but you could call it something different), -h is the “host” you are pinging, -l is the name of the “localhost”, i.e. the machine you are pinging from, and -e is the email address (or multiple email addresses) you want to send any alarm mails to.

I have an “email to SMS” address as one of the alarm message recipient, so I get a text (SMS) message on my GSM mobile phone if one of the servers I’m monitoring has been down for 10 minutes or 25 minutes. You could also run a whole network monitoring project with this, using it to ping routers or switches.

I’ll put the script into the posting below, but in order to run this, you also need a table in a database which looks like this:

CREATE TABLE mon_host_ping (
mon_host_ping_id int(5) NOT NULL auto_increment,
mon_host_ping_hostname varchar(128) NOT NULL default ‘’,
mon_host_ping_factor bigint(16) default NULL,
mon_host_ping_lastupdt timestamp(14) NOT NULL,
PRIMARY KEY (mon_host_ping_id),
UNIQUE KEY mon_host_ping_hostname (mon_host_ping_hostname)
) TYPE=MyISAM;

- You should just be able to cut-and-paste that into the database

I just run this script on a cron job once a minute (feel free to alter the values you use) for each server to be monitored. The line in the crontab looks like this:

* * * * * /usr/bin/php /home/username/php-monitor/ping-host.php -h target.example.com -l pinger.example.com -e myaddress@example.com,+316555544445@sms.orange.nl

Every time you add a new server to the ping list in your crontab you’ll also need to add a row in the mon_host_ping table in the database with its mon_host_ping_factor set to zero:

mysql> insert into mon_host_ping values(NULL, “target.example.com”, 0, NOW());
Query OK, 1 row affected (0.00 sec)

Okay, so now here’s the code for the script, ping-host.php :

<?php

## This script was originally published by Sam Critchley on 2005-10-25
##See http://blog.a2b.cc for more details and check out http://www.a2b.cc
##to see a great (geo)location-based search engine while you’re at it!

## MySQL config section
// Define users, passwords, etc
DEFINE (DB_USER, “dbusername”);
DEFINE (DB_PASSWORD, “dbpassword”);
// Define the host which the database is running on (usually localhost)
DEFINE (DB_HOST, “localhost”);
// Define the name of the database being used
DEFINE (DB_NAME, “dbdatabasename”);

// Connect to the MySQL server
$db_connection = @mysql_connect (DB_HOST, DB_USER, DB_PASSWORD) or die (‘Could not connect to the MySQL server sorry: ‘ . mysql_error());
// Select the right database
mysql_select_db (DB_NAME) or die (‘Could not select the database: ‘ . mysql_error());
## End MySQL config section

## Main script
// Work out the variables from the arguments on the command line
// First get the -h, -l and -e arguments from the command issued
// and put them into an array call $getoptarray
$getoptarray = getopt(“h:l:e:”);
// Then derive the pinged hostname, the source machine, and the email address
// to send a warning mail to, from the argument-derived variables
$hostname = $getoptarray[h];
$localhost = $getoptarray[l];
$monitoremailaddress = $getoptarray[e];

// Now run an exec command to ping the hostname and grab the output
$str=exec(“ping -c 1 -w 1 $hostname”,$a,$a1);

// If there’s some output from the ping command then the ping has succeeded
if(strlen($str)>1){

     // Ping response has been received, therefore can update the database record to set
     // mon_host_ping_factor back to 0
     // The script uses a database table called mon_host_ping and has columns
     // mon_host_ping_hostname = hostname of the host to be pinged
     // mon_host_ping_factor = number of times in a row host has been pinged unsuccessfully
     // This database query sets mon_host_ping_factor to 0 if there’s a successful ping
     $query = “update mon_host_ping set mon_host_ping_factor = 0 where mon_host_ping_hostname = ‘$hostname’”;
     $query_db=mysql_query($query, $db_connection) or die(“Could not run the SQL Query”);

// If there is no output from the ping command then the ping has not succeeded
// and you should generate an alarm mail if it hasn’t succeeded for 10 minutes
// or 25 minutes (alter these values to suit)
} else {

     // Generate a database query adding 1 to mon_host_ping_factor if the ping is
     // unsuccessful
     $query2 = “update mon_host_ping set mon_host_ping_factor = mon_host_ping_factor+1 where mon_host_ping_hostname = ‘$hostname’”;
     $query_db2=mysql_query($query2, $db_connection) or die(“Could not run the SQL Query”);

     // Now go and grab the mon_host_ping_factor back again, and send a mail if
     // it’s equal to 10 or 25 (minutes assuming you’re running this script on a
     // cron job every 1 minute)

     // Generate a MySQL query to work out what mon_host_ping_factor is
     $query3 = “select * from mon_host_ping where mon_host_ping_hostname = ‘$hostname’”;
     $query_db3=mysql_query($query3, $db_connection) or die(“Could not run the SQL Query”);
     // and then put the result into an array
     $row = @mysql_fetch_object($query_db3);
     // And put the mon_host_ping_factor into a variable
     $hostfactor = $row -> mon_host_ping_factor;

     // Now send an alert email to the address specified in the command line if
     // the ping has been unsuccessful 10 or 25 minutes in a row
     if (($hostfactor == 10) or ($hostfactor == 25)) {
        // Set the body of the message
        $emessage = “ALERT - $hostname unpingable from $localhost for $hostfactor min”;
        // Set the name for the From: part of the email
        $myname = “My Service server monitoring”;
        // Set the originator’s email address
        $myemail = “monitoring@example.com”;
        // Get the address to which the email will be sent from the command line variable
        $site_email = $monitoremailaddress;

        // Now set the headers to be added to the email
        $headers .= “MIME-Version: 1.0\r\n;
        $headers .= “Content-type: text/html; charset=iso-8859-1\r\n;
        $headers .= “From: “.$myname.” < “.$myemail.“>\r\n;
        $headers .= “X-Mailer: My Service Mailserv”;

        // Now use the PHP mail() function to send the email to the recipient(s)
        mail($site_email, “ALERT - $hostname unpingable from $localhost for $hostfactor min”, $emessage, $headers);

     }
  }

## End main script

?>

I also learnt how to use the PHP getopt() function properly to import command-line arguments into a PHP script. If you’ve read this far, you may have noticed that the script used the following PHP line:

$getoptarray = getopt(“h:l:e:”);
// Then derive the pinged hostname, the source machine, and the email address
// to send a warning mail to, from the argument-derived variables
$hostname = $getoptarray[h];
$localhost = $getoptarray[l];
$monitoremailaddress = $getoptarray[e];

This finally worked, but I had to try various combinations to get it working:

$hostarray = getopt(“h:”);
 $hostarray = getopt();
 $hostarray = getopt(“h:”); $localhost = getopt(“l:”);

I finally worked out that you need to put all the arguments you’re expecting in the original getopt() function as it can only be called once on a script run from the command line - in this case the arguments are all dumped into the $getoptarray array and you can then pull them out individually using something like this:

$hostname = $getoptarray[h];
$localhost = $getoptarray[l];
$monitoremailaddress = $getoptarray[e];

Any queries, just post a comment. Better still, have a look at A2B, download the free GPS software, add your blog, pass on the recommendation to a few other people, and then post a comment. ;-)

41 Responses to “PHP script for server ping monitoring”

  1. Dave
    July 10th, 2006 | 8:43 pm

    thanks so much for this, have been looking for something similar for a while. Cant say thank you enough :D

  2. Sam
    July 10th, 2006 | 10:12 pm

    Hi Dave. You’re welcome! Hope it works okay on your machine. Cheers, Sam

  3. Malaka
    September 22nd, 2006 | 11:47 am

    Thanks a lot for sharing this code.

  4. November 25th, 2006 | 10:34 am

    Hi Sam.

    Nice script but have an improvement for you. The problem lie in that we had a bunch of these scripts on many servers at different datacenters.

    Should the server that is doing the pinging go down, many messages build up. When the server is online, a rash of emails are received. To combat this, if the ping is unresponsive, it should also ping google, yahoo or both to determine whether the box even has a live connection.

    Just my 2 cents.
    Craig

  5. May 13th, 2007 | 5:08 am

    Hi My Name Is ivamgx.

  6. AnferTuto
    July 28th, 2007 | 2:40 am

    Hola faretaste
    mekodinosad

  7. September 4th, 2007 | 4:43 am

    I appreciate it; but the above code contains some of syntax errors hard to trace like UNEXPECTED_TLINENUMBER; so i decided to write my own function to ping the server and then i run it as a cron job.

    —————————————————

    —————————————————-

  8. September 4th, 2007 | 4:44 am

    ?

    function ping($host, $port, $timeout) {
    $tB = microtime(true);
    $fP = fSockOpen($host, $port, $errno, $errstr, $timeout);
    if (!$fP) { return “down”; }
    $tA = microtime(true);
    return round((($tA - $tB) * 1000), 0).” ms”;
    }

    echo ping(”www.google.com”, 45450, 2);

    ?

  9. September 27th, 2007 | 6:53 am

    Nice to view it i will do later and Thanks for sharing………..

  10. October 30th, 2007 | 12:58 pm

    bodog fight recap…

    splices defile monkish …

  11. November 19th, 2007 | 9:50 am

    Follow these guidelines and you will build that new home with little, or no, problems. bathroom renovation can help…

  12. December 16th, 2007 | 1:25 pm

    hey thanks bro this is great same me having to write my own code works great i have also intergrated an sms function through clickatell so i get an sms.thanks again

    cheers

  13. hadi
    January 19th, 2008 | 6:58 pm

    wow…thanks a lot for sharing, but i had a few question, is there any interface/map for this script (so it will appear like a what’s up gold where you can add/edit map for your monitored device) and connect it thru an sms gateway will be much nicer….

    thanks
    /hadi

  14. January 29th, 2008 | 3:40 am

    william hill betting…

    nebula Yonkers!solidified outstanding …

  15. March 13th, 2008 | 8:22 am

    it seems like e very good web site but my English is not good. It would be great if it might be availible in other languages too. Thanks.

  16. April 14th, 2008 | 5:46 pm

    Twilight sex….

    Twilight sex….

  17. June 4th, 2008 | 6:03 am

    bigger dick = better sex…

    2 inches. average black male penis size This study was done on almost 3,000 men from 27 countries. jelquing exercises How to measure your penis girthMy favorite penis exercise site, Penis Health, offers the following advice when measuring girth. First …

  18. July 6th, 2008 | 1:29 am

    auto insurance quotes new jersey…

    specificity stored dwindling peanut,snapped successes …

  19. July 18th, 2008 | 12:15 pm

    Interesting ideas… I wonder how the Hollywood media would portray this?

  20. August 8th, 2008 | 4:52 pm

    do you know any information about this in english?

  21. August 19th, 2008 | 10:12 pm

    Fajna stronka, bede tu wpadal czesciej, pozdro

  22. September 7th, 2008 | 9:49 pm

    actuators controlling damper doors on buick riviera indigo jazz new york french erotic film mp3

  23. November 6th, 2008 | 1:11 am

    mdyayayaya ….. * Many people think *…. the author thanks for the post!

  24. DDDepressionnn
    November 20th, 2008 | 7:13 pm

    There has come winter :(
    It became cold and cloudy!
    Mood very bad :(
    Depression Begins

  25. DDDDepressionnnn
    November 21st, 2008 | 3:03 am

    Depression Depression Depression aaaaaaaa
    HEEEEELP :( :( :(
    I hate winter! I want summer!

  26. wintervssummer
    November 29th, 2008 | 4:10 pm

    I very much love summer :)
    Someone very much loves winter :(
    I Wish to know whom more :)
    For what you love winter?
    For what you love summer? Let’s argue :)

  27. January 22nd, 2009 | 12:22 am

    awesome and very useful script, thank you.

  28. osobo
    February 17th, 2009 | 4:01 pm

    Новый способ давления на кандидата на пост Главы г. Химки

    Новый способ “наказать” тех, кто посмел участвовать в выборной кампании не на стороне действующей власти изобрели правоохранительные органы г.о. Химки.
    Руководствуясь не нормой закона, а чьей-то “волей” сотрудники милиции решили “проверить” все фирмы, внесшие денежные средства в избирательный фонд неудобных кандидатов.
    Начались “проверки” с телефонных звонков - где директор, сколько человек работает на фирме. После чего последовали “письма счастья” с просьбой предоставить всю бухгалтерскую документацию, учредительные документы фирмы, и даже, план экспликации БТИ.
    Такие запросы химкинским фирмам рассылает 1 отдел Оперативно-розыскной части № 9 Управления по налоговым преступлениям ГУВД Московской области за подписью начальника подполковника милиции Д.В. Языкова.
    И всё это в то время, когда Президент дал прямое указание правоохранительным органам о прекращении всех незаконных проверок малого и среднего бизнеса. С это целью внесены изменения в Федеральный закон “О милиции” - из статьи 11 этого закона исключены пункты 25 и 35, на основании которых ранее правоохранительные органы имели право проверять финансово-хозяйственную деятельность предприятий.
    Видно, об изменениях действующего законодательства местные правоохранительные органы не уведомлены. И не смотрят телепередачи с выступлениями Президента.
    Может быть, эта публикация подвигнет их к исполнению указаний Президента, а также к изучению и соблюдению действующего законодательства

  29. натяжные потолки
    March 12th, 2009 | 9:16 pm

    ремонт квартир натяжные потолки

  30. taumbgaugsFab
    May 19th, 2009 | 7:08 am

    Работаю менеджером. Хочу сделать интернет магазин. Порекомендуйте человека или организацию, кто поможет мне в этом. Главное чтоб человек, который его делает был адекватный и недорого.

  31. May 24th, 2009 | 12:48 pm

    Really appreciate your GOOD Work SAM… Keep it up. This is very useful tips…
    My Question: how do we specifiy server path for a server an intranet.

    Cheers

  32. May 24th, 2009 | 7:59 pm

    Благодарствую!!! У Вас часто появляются очень интересные мысли! Очень поднимаете мой настрой.

  33. July 7th, 2009 | 2:21 pm

    За статью спасибо, все по делу, достаточно много кто это использует

  34. July 13th, 2009 | 11:19 am

    Я могу проконсультировать Вас по этому вопросу.

  35. July 21st, 2009 | 1:29 am

    Спасибо, очень интересная заметка.

  36. July 22nd, 2009 | 6:17 pm

    Действительно интересно было почитать :) Попробуем-с тоже ответить в ближайших темах.

  37. July 22nd, 2009 | 11:23 pm

    P6DuZQ fgoG62mvVof47J1fCaLkg

  38. July 27th, 2009 | 3:38 am

    This is a unique post because I was “googling” similar terms earlier on and somehow came across this…..I’l be sure to inform others of your website!

  39. August 30th, 2009 | 10:47 pm

    I thought I wasnt going to like this blog but more I read the more I liked it.

  40. September 25th, 2009 | 8:18 am

    Iphone 3GS 32Gb оптом и в розницу.
    До 10шт. 28000р.
    До 30шт. 27000р.
    До 50шт. 26500р.
    Свыше 50шт. цена договорная.
    Находимся мы в России г. Калининград
    100% предоплата. Доставка максимум 15 дней. Перевод денег через любые способы переводов.
    Возможен самовывоз из г. Калининград, без осуществления предоплаты.

    ICQ 356391652
    моб. 891114622668

  41. June 6th, 2010 | 9:04 am

    Люди лгут не для того, чтобы с чем-то бороться, а для того чтобы к чему-то стремиться! В мире без лжи не бывает перемен…

Leave a reply