Simple Load Monitor script (no database)

posted by Allan@TechCrammer @ 12:01am, Tuesday 30 December 2008.

I created this simple little load monitor script over four years ago. Since then we have used Zabbix and now a much more complex home brew monitor that also utilizes outside alerts from 3rd parties, such as Alertra. My objective was that I wanted to be able to check the loads of all of our Linux servers at any location with a browser. I had a bash script that I used with watch through a secure shell session, though I wanted this Web based (shouldn't everything be in a browser?). Of course you can adapt this concept to do much more, such as grabbing disk space usage, and this example is really just a quick hack.

So with that in mind please use this at your own risk with NO WARRANTY provided. Also be aware this is not be the most security conscious script out there. At the very least keep the PHP files under a .htaccess password protected directory, though also keep in mind reading/writing files can be dangerous and use this with caution or better yet fix any security flaws you see and post back and I can update for everyone. I stripped out some comments and other information that was specific to the site it was hosted on.

We use two PHP files, reader.php and writer.php, and one bash script. We use a client/server type concept between the bash script sending out data, to the writer.php file accepting it. The reader.php is just for looking at the data collected.

writer.php

<?
// List of valid server names
$server_list = "server1,server2,server3";

// Extra security precaution
if (strstr($server_list, $server)) {

    // Querystring server name and .cfg
    $file = $server.'.cfg';

    // Write the new process load
    $fd = fopen($file, "w");
    fwrite($fd, $load);
}
?>

You don't really need a list of server names though this gives me some more piece of mind from a security standpoint. The writer.php takes the querystring variables "server" and "load". It creates a new file using the name of the server and adds a ".cfg" suffix and then inputs the load into the file as the only data. This seems a little odd and could be combined into one file, though if I was going to do that it might as well go into a database.

reader.php
 <?
// Header
echo "<HTML><HEAD><TITLE>LoadMon</TITLE>";
echo "<META HTTP-EQUIV='refresh' content='25;URL=https://yoursite.com/protected/loadmon/reader.php'>";
echo "</HEAD><BODY LEFTMARGIN=0 TOPMARGIN=0 MARGINHEIGHT=0 MARGINWIDTH=0>";
echo "<font size=-2>Current Time: ".date("H:i:s")."</font>";
echo "<font size=-2>&nbsp;&nbsp;&nbsp;&nbsp;<A HREF='https://yoursite.com/protected/loadmon/reader.php'>Refresh</A></font>";
echo "<TABLE CELLPADDING=2 CELLSPACING=2 BORDER=0>";

// Define the full path to the loadmon folder
$path = "/www/path/loadmon/";

// Open the folder
$dir_handle = @opendir($path) or die("Unable to open $path");

// Loop through the files
while (false !== ($file = readdir($dir_handle))) {

    // Prevent this file itself being shown
    if(substr($file,-3) != "cfg")
    continue;

    // Display the results
   $fd = fopen($file, "r");
   $fstring = fread($fd, filesize($file));

   echo "<TR><TD BGCOLOR=#CCFFFF><FONT SIZE=-2>".str_replace(".cfg", "", $file)."</FONT></TD>";
   echo "<TD BGCOLOR=#CCFFFF><FONT SIZE=-2>".$fstring."</FONT></TD>";
   echo "<TD BGCOLOR=#FFFFFF><FONT SIZE=-2>".date("d/m/y H:i:s",filemtime($file))."</FONT></TD></TR>";
}

// Close it
closedir($dir_handle);

// Footer
echo "</TABLE></BODY></HTML>";
?>


The "reader.php" is the display part of the code and uses a meta refresh which you can adjust as you like. I use a link from another page to make it open in a small window with no toolbar. Something like the following:
<span class="popup" onClick=javascript:window.open("http://yoursite.com/protected/loadmon/reader.php", "blank","toolbar=no,width=200,height=250")>Load Monitor</span>

Its job is to recurse through the directory and open the .cfg files and display the content. By all means you could be creative here and turn the string into an integer and show as red if it was a load higher than expected. A nice feature here is that it gives you the date of the file so you can be sure the script is getting new data.

loadmon.bash
#!/bin/bash
myserver="server1"
myload=`cat /proc/loadavg |cut -f1 -d' '`

curl --silent -u "user:password" -m 5 "https://yoursite.com/protected/loadmon/writer.php?load=$myload&server=$myserver" -o /dev/null

The last file is a bash script "loadmon.bash" that you need to place on each server that will report its load to you. It takes the current load from the proc directory (probably a better way to do this) and then uses curl to send it out to the writer.php file. I am using .htaccess and have to specify the user and password. I remember this being a pain figuring this out though need the "--silent" option to get it to work, though was awhile back and may have changed. The "-m" option just gives it a timeout and is not mandatory.

Of course you need a way to make this script happen and I just made a file in my /etc/cron.d directory /etc/cron.d/loadmon that runs the script every 5 minutes.
#Custom Load Monitoring
*/5 * * * * root /path/loadmon.bash

You can run as often as you like. I just didn't want all the servers reporting too quickly that I am hitting the web server so much all at the same time.

I realize this is just a rough concept, though I do hope you at least you may get some ideas for a launch pad to create your own custom load monitor.

-Allan

  • Del.icio.us
  • Digg
  • Technorati
  • Blinklist
  • Furl
  • Reddit
  • Facebook

Comments

Submit Your Comment

You are not logged in.

Log In