dkinzer
01-18-2007, 01:13 PM
I've been experiencing bouts of high server load recently so I decided to create a script (below) to check the server load and to send me email if the load over the last 15 minutes gets too high. I have set up a crontab entry to run this script every 15 minutes.
To use this script, which can be run either as a web script or a command, you'll need to change some of the configuration parameters, particularly those related to email and your domain name.
I currently have the per-CPU load threshold for email notification set to 4.0; you may want to adjust that up or down to suit your needs. I've seen some references indicating that a per-CPU load of 1.0 is an acceptable level. I've rarely seen it that low here at BlueHost; it typically runs in the 1.5 to 2.5 range and my site performance is OK at those levels. When the per-CPU load is in the 8.0 to 10.0 range my site is dog slow - clearly unacceptable.
<?php
// configuration parameters, change to suit
// email parameters
$domain = "yourdomain.com";
$mailTo = "somebody@somewhere.com";
$mailFrom = "webmaster@$domain"; // this must be a valid email address
// specify the load threshold (per CPU) for email notification
$loadLimit = 4.0;
// check the server load
checkServerLoad($loadLimit, $domain, $mailTo, $mailFrom);
// -----------------------------------------------------------------------
// nothing should need to be changed below here
// -----------------------------------------------------------------------
function checkServerLoad($loadLimit, $domain, $mailTo, $mailFrom)
{
// check for being invoked as a web page or as a script,
// select an appropriate line terminator
$term = isset($_SERVER['DOCUMENT_ROOT']) ? "<br>\n" : "\n";
// get the uptime data for the server
// $avgs[1] - load during the last 1 minute interval
// $avgs[2] - load during the last 5 minute interval
// $avgs[3] - load during the last 15 minute interval
$uptimeInfo = @exec('uptime');
preg_match("/averages?: ([0-9\.]+),[\s]+([0-9\.]+),[\s]+([0-9\.]+)/", $uptimeInfo, $avgs);
// determine the number of processors on the server
$procInfo = @file_get_contents('/proc/cpuinfo');
$numProcs = preg_match_all("/processor[ \t]+:[ \t]+[0-9]+/", $procInfo, $matches);
echo "Load averages: " . $avgs[1] . ", " . $avgs[2] . ", " . $avgs[3] . " (" . $numProcs . " CPUs)" . $term;
// see if the per-CPU load over the last 15 minutes has been excessive
if ($avgs[3] >= ($numProcs * $loadLimit))
{
echo "The server load has been too high, sending email notification." . $term;
// email subject line
$subject = "Excessive server load for $domain";
// email headers
$headers = "";
$headers .= "From: $mailFrom\n";
$headers .= "Return-Path: $mailFrom\n";
$headers .= "Message-ID: <" . md5(uniqid(time())) . "@$domain>";
$headers .= "MIME-Version: 1.0";
$headers .= "Content-type: text/plain; charset=iso-8859-1\n";
$headers .= "Content-transfer-encoding: 8bit\n";
$headers .= "Date: " . date('r', time()) . "\n";
$headers .= "X-Priority: 3\n";
$headers .= "X-MSMail-Priority: High\n";
$headers .= "X-Mailer: PHP\n";
$headers .= "X-MimeOLE: Produced By $domain\n";
// email message
$message = "";
$message .= "Load averages for the $domain web server ($numProcs CPUS):\n";
$message .= " " . $avgs[1] . ", " . $avgs[2] . ", " . $avgs[3] . "\n";
$message .= "\n";
$message .= "Contact BlueHost Customer Support at 1.888.401.4678\n";
$message .= "Your server is " . @exec('hostname') . ".\n";
$resp = mail($mailTo, $subject, $message, $headers);
echo "Mail sent to " . $mailTo . ", response code = " . $resp . "." . $term;
$stat = 1;
}
else
{
// the load is OK, no email sent
$stat = 0;
}
return($stat);
}
?>
To use this script, which can be run either as a web script or a command, you'll need to change some of the configuration parameters, particularly those related to email and your domain name.
I currently have the per-CPU load threshold for email notification set to 4.0; you may want to adjust that up or down to suit your needs. I've seen some references indicating that a per-CPU load of 1.0 is an acceptable level. I've rarely seen it that low here at BlueHost; it typically runs in the 1.5 to 2.5 range and my site performance is OK at those levels. When the per-CPU load is in the 8.0 to 10.0 range my site is dog slow - clearly unacceptable.
<?php
// configuration parameters, change to suit
// email parameters
$domain = "yourdomain.com";
$mailTo = "somebody@somewhere.com";
$mailFrom = "webmaster@$domain"; // this must be a valid email address
// specify the load threshold (per CPU) for email notification
$loadLimit = 4.0;
// check the server load
checkServerLoad($loadLimit, $domain, $mailTo, $mailFrom);
// -----------------------------------------------------------------------
// nothing should need to be changed below here
// -----------------------------------------------------------------------
function checkServerLoad($loadLimit, $domain, $mailTo, $mailFrom)
{
// check for being invoked as a web page or as a script,
// select an appropriate line terminator
$term = isset($_SERVER['DOCUMENT_ROOT']) ? "<br>\n" : "\n";
// get the uptime data for the server
// $avgs[1] - load during the last 1 minute interval
// $avgs[2] - load during the last 5 minute interval
// $avgs[3] - load during the last 15 minute interval
$uptimeInfo = @exec('uptime');
preg_match("/averages?: ([0-9\.]+),[\s]+([0-9\.]+),[\s]+([0-9\.]+)/", $uptimeInfo, $avgs);
// determine the number of processors on the server
$procInfo = @file_get_contents('/proc/cpuinfo');
$numProcs = preg_match_all("/processor[ \t]+:[ \t]+[0-9]+/", $procInfo, $matches);
echo "Load averages: " . $avgs[1] . ", " . $avgs[2] . ", " . $avgs[3] . " (" . $numProcs . " CPUs)" . $term;
// see if the per-CPU load over the last 15 minutes has been excessive
if ($avgs[3] >= ($numProcs * $loadLimit))
{
echo "The server load has been too high, sending email notification." . $term;
// email subject line
$subject = "Excessive server load for $domain";
// email headers
$headers = "";
$headers .= "From: $mailFrom\n";
$headers .= "Return-Path: $mailFrom\n";
$headers .= "Message-ID: <" . md5(uniqid(time())) . "@$domain>";
$headers .= "MIME-Version: 1.0";
$headers .= "Content-type: text/plain; charset=iso-8859-1\n";
$headers .= "Content-transfer-encoding: 8bit\n";
$headers .= "Date: " . date('r', time()) . "\n";
$headers .= "X-Priority: 3\n";
$headers .= "X-MSMail-Priority: High\n";
$headers .= "X-Mailer: PHP\n";
$headers .= "X-MimeOLE: Produced By $domain\n";
// email message
$message = "";
$message .= "Load averages for the $domain web server ($numProcs CPUS):\n";
$message .= " " . $avgs[1] . ", " . $avgs[2] . ", " . $avgs[3] . "\n";
$message .= "\n";
$message .= "Contact BlueHost Customer Support at 1.888.401.4678\n";
$message .= "Your server is " . @exec('hostname') . ".\n";
$resp = mail($mailTo, $subject, $message, $headers);
echo "Mail sent to " . $mailTo . ", response code = " . $resp . "." . $term;
$stat = 1;
}
else
{
// the load is OK, no email sent
$stat = 0;
}
return($stat);
}
?>