PrintLogo

A Simple Perl Load Monitoring Script




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.

--Agatha



This article comes from NetAdminTools:
http://www.netadmintools.com/

The URL for this story is:
http://www.netadmintools.com/art314.html

Copyright 1997-2007 NetAdminTools.com. Read our Terms of Use.