I wondered how to monitor load on my GNU/Linux boxen. Sure, there are a lot of canned apps out there. But what if I wanted to use Perl? (IUD SIS, you must use Perl, cuz Perl’s the best… Readin’ from my Camel book like you wanted me… script the pain away…) Anyhoo… I wanna use Perl. I want to trigger events based on the current load and track the previous load state. The first reaction is to search for a module, right? Well, if you are monitoring GNU/Linux boxen, there is a very simple way to get load stats using the proc filesystem. Enough! Let’s see some code:
| %servers= (
srv-33 => "super",
srv-3 => "ok",
srv-44 => "messed up",
srv-34 => "thanks for asking",
);  
for $server (keys %servers){
print $server," - ",$servers{$server},"\n";
}   
 | 
The above script sets up a hash of server names with text values. The cool thing about using a hash is that the server name can be used as a friendly name in the output of the script. Here is the output of the above script:
| srv-34 - thanks for asking srv-44 - messed up srv-3 - ok srv-33 - super | 
One quick and dirty way to get load stats is to cat /proc/loadavg. I’ve set up keys to the other servers I’m monitoring, so I can grab the remote load stats by:
| [root@ares simplestats]# ssh root@srv-33 "cat /proc/loadavg" 0.03 0.04 0.24 1/26 6618 [root@ares simplestats]# | 
Let’s add this to the script:
| %servers= (
srv-33 => "super",
srv-3 => "ok",
srv-44 => "messed up",
srv-34 => "thanks for asking",
ares => "super",
);  
for $server (keys %servers){
@ss=split " ",`ssh root\@$server "cat /proc/loadavg"`;
print $server," - old status:",$servers{$server},"\n";
print "Current Load: ",$ss[0]," ",$ss[1]," ",$ss[2],"\n";
}   
 | 
One tricky part of the above script is using the backticks around the ssh command so that it will assign the output to a string. The output of the above script:
| srv-34 - old status:thanks for asking Current Load: 0.08 0.03 0.00 ares - old status:super Current Load: 0.15 0.12 0.09 srv-44 - old status:messed up Current Load: 0.01 0.00 0.00 srv-3 - old status:ok Current Load: 0.24 0.05 0.02 srv-33 - old status:super Current Load: 0.15 0.03 0.01 | 
If we want to trigger on certain conditions, we could use this script:
| %servers= (
srv-33 => "super",
srv-3 => "ok",
srv-44 => "messed up",
srv-34 => "thanks for asking",
ares => "super",
);
for $server (keys %servers){
@ss=split " ",`ssh root\@$server "cat /proc/loadavg"`;
print $server," - old status:",$servers{$server},"\n";
print "Current Load: ",$ss[0]," ",$ss[1]," ",$ss[2],"\n";
if ($ss[0] == 0.00){
$servers{$server}="super";
}
elsif ($ss[0] < 0.03){
$servers{$server}="ok";
}
elsif ($ss[0] < 0.11){
$servers{$server}="thanks for asking";
}
else {
$servers{$server}="messed up";
}
print $server," - new status:",$servers{$server},"\n";
}
 | 
The output looks like this:
| srv-34 - old status:thanks for asking Current Load: 0.00 0.00 0.00 srv-34 - new status:super ares - old status:super Current Load: 0.14 0.08 0.03 ares - new status:messed up srv-44 - old status:messed up Current Load: 0.00 0.00 0.00 srv-44 - new status:super srv-3 - old status:ok Current Load: 0.07 0.02 0.00 srv-3 - new status:thanks for asking srv-33 - old status:super Current Load: 0.13 0.03 0.01 srv-33 - new status:messed up | 
Of course, you could do anything you want based on the load. If you are monitoring a pool of servers, you could route new connections to other boxes if the load gets too high, etc.


