PDA

View Full Version : Monitoring server load



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);
}
?>