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
|
|