class to check if servers are down

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

Post Reply
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

class to check if servers are down

Post by s.dot »

This following class will check X amount of servers to see if they can be pinged. If the ping request reports anything other than a 0% loss of packets, you will be emailed alerting you that that server may be down. You should set this on a shedule to run every X minutes.

I tested this on Windows. Whether or not it would work on a linux server, I don't know.

I'm going to configure mine to TXT my cell phone, but I figure i'd produce something useful while I was at it! So here it is:

The Code

Code: Select all

<?php

/* This class will check X amounts of servers to see if they can be pinged.
*  If they can't be pinged, or ping reports more than a 0% loss of packets, 
* you will be emailed.
*
* author: scottayy@gmail.com
*/

class serverup
{
	var $servers = array();
	var $output;
	
	//add a server ip to be tested
	//@param string $server_ip
	function add_server($server_ip)
	{
		$this->servers[] = $server_ip;
	}
	
	//check if up
	//@param string $email
	function check($email)
	{
		foreach($this->servers AS $server)
		{
			
			//check if output array is empty
			if(!empty($this->output))
			{
				$this->output = array();
			}
			
			//execute ping
			exec('ping '.$server, $this->output);
			
			//check the output
			if($percent_loss = $this->check_output())
			{
				if($percent_loss !== true)
				{
					$msg = 'Server '.$server.' may be down. Ping is reporting a '.$percent_loss.'% ' .
					'loss of packets on '.date("n-d-Y \a\\t g:i A").".\n";
				}
			} else
			{
				$msg = 'Server '.$server.' may be down.  Ping reports it to be unreachable on '.
				date("n-d-Y \a\\t g:i A").".\n";
			}
			
			//mail results if server may be down
			if(!empty($msg))
			{
				mail($email, $subject='Server May Be Down', $msg);
			}
		}
	}
	
	//checks ping result for % of lost pings
	function check_output()
	{
		$output = implode("\n", $this->output);
		if(preg_match("/([\d]{1,3})% loss/", $output, $matches))
		{
			if($matches[1] > 0)
			{
				return $matches[1];
			} else
			{
				return true;
			}
		} else
		{
			return false;
		}
	}
}
The Test

Code: Select all

$serverup = new serverup();
$serverup->add_server('1.1.1.1');
$serverup->add_server('1.1.1.1.1.1.1');
$serverup->check('you@email.com');
The Output (emails that it sent)

Code: Select all

Server 1.1.1.1 may be down. Ping is reporting a 100% loss of packets on 10-22-2006 at 11:09 PM.

Code: Select all

Server 1.1.1.1.1.1.1 may be down.  Ping reports it to be unreachable on 10-22-2006 at 11:09 PM.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Wow, sending the output to a text message on your phone is easy!

I just replace my email in

Code: Select all

$serverup->check('you@email.com');
with

Code: Select all

$serverup->check('0123456789@cwemail.com');
That's how it's done for centennial. For most cell phone carriers its yournumber@somedomain.com.

Now I will get txt msg alerts when my server goes down! sooooooo cool 8)
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

I was thinking the next thing you could do was eliminate the system call using a native PHP implementation of ping. PEAR's got something like that.

If the server does go down, I wonder whether or not you'd like to be constantly be annoyed by text messages every (insert interval you're running script here).

You may also choose to regard this as a bug, although it won't manifest: if the computer running the script is disconnected from the Internet, it will report it incorrectly down. Of course, you won't get an email since it's not connected either.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Ambush Commander wrote:I was thinking the next thing you could do was eliminate the system call using a native PHP implementation of ping. PEAR's got something like that.
Cool, I'll look into that.
Ambush Commander wrote:If the server does go down, I wonder whether or not you'd like to be constantly be annoyed by text messages every (insert interval you're running script here).
Heck yes :P time = $$
Ambush Commander wrote:You may also choose to regard this as a bug, although it won't manifest: if the computer running the script is disconnected from the Internet, it will report it incorrectly down. Of course, you won't get an email since it's not connected either.
Very true.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Alright, so, I have this running on my PC every 10 minutes.

The task is..

C:\php\php.exe C:\Apache2\htdocs\tasks\serverup.class.php

Every 10 minutes the command prompt window pops up while it's completing. Takes about 30 seconds, and it pops up on top of everything. Is there a way to run this in "silent" mode. Or at least have it minimized while it's running?
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

that's so cool!
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

scottayy wrote:Alright, so, I have this running on my PC every 10 minutes.

The task is..

C:\php\php.exe C:\Apache2\htdocs\tasks\serverup.class.php

Every 10 minutes the command prompt window pops up while it's completing. Takes about 30 seconds, and it pops up on top of everything. Is there a way to run this in "silent" mode. Or at least have it minimized while it's running?
Maybe something like:

Code: Select all

<?php

set_time_limit(0);
ignore_user_abort();

echo "Dude -- Kill the browser, it's fine!";
flush();

do {
    $serverup = new serverup();
    $serverup->add_server('1.1.1.1');
    $serverup->add_server('1.1.1.1.1.1.1');
    $serverup->check('you@email.com');
    sleep(60 * 10);
} while (true);

?>
Open it in FF, wait for that text to appear, kill the window and see if it keep going. Technically it should do :)
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Set "Run as" to "NT AUTHORITY\SYSTEM"
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Ambush Commander wrote:Set "Run as" to "NT AUTHORITY\SYSTEM"
worked like a charm.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Post by Mordred »

If the computer running the script is disconnected from the Internet, it will report it incorrectly down.
If pinging google doesn't work, assume the local internet connection is down ;) Of course this is better achieved by pinging a collection of servers and checking if at least one of them is reachable.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Mordred wrote:
If the computer running the script is disconnected from the Internet, it will report it incorrectly down.
If pinging google doesn't work, assume the local internet connection is down ;) Of course this is better achieved by pinging a collection of servers and checking if at least one of them is reachable.
The way you check if it's a network issue with heartbeat (and I guess it applies generally) is like this (you need two machines within distance of getting a cable between them). Just connect a serial cable between the two machines. Check for life over the serial connection. If that's alive try it over the eth0 connection. If eth0 doesn't respond, but serial does something's up with the local network.
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Post by Mordred »

This will only work for a really "local" connection ;)
What about if your ISP, or the router in your building is down? You need to check connectivity with machines which are several hops from you. But still, pinging the first two hops can really help in checking if it's the connectivity problem is on the local or on the remote site.
Actually that's what traceroute is for, so it might be better to include a stripped down traceroute report if the pings fail.
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

Makes me wonder why we have SNMP...
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

Ambush Commander wrote:I was thinking the next thing you could do was eliminate the system call using a native PHP implementation of ping. PEAR's got something like that.
There's no such thing as php ping implementation, and I doubt it would ever be done for strictly technical reasons: ping requires root permissions, and php interpreter usually don't have them.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Oh, I see, the PEAR class simply wraps the ping call so that it works across platforms. Still, it's probably a better idea to use Network_Ping for portability.
Post Reply