Re: [CODE] Graphing individual CPUs on a Linux SMP (multiprocessor) machine
Christian Hammers <[email protected]>
| Newsgroups | gmane.network.cricket.user |
|---|---|
| Message-ID | <[email protected]> |
On Wed, Aug 23, 2006 at 06:13:12PM +0200, Claus Koch wrote:
> will you be so kind and publish your plugin here? I also need this kind
> of data and would be happy to help with testing.
Of course, I just wanted to test it for a day. The script is a shrinked
down version of another plugin and includes hardcoded values but at least
I commented it a bit so that it may be helpful to others and maybe put
on the contrib page.
bye,
-christian-
#!/usr/bin/perl -W
#
# snmpd plugin providing usage statistics of individual CPUs on Linux SMP.
#
# This plugin provides the output of "mpstat -P ALL 1 1". The data is
# refreshed every minute.
#
# To active this plugin put this line into /etc/snmp/snmpd.conf:
# pass_persist .1.3.6.1.4.1.4242.2 /usr/local/maint/mpstat-snmp-plugin.pl
#
# Debugging is possible by setting the global $DEBUG=1 and watch syslog.
#
# MIB Tree:
# .1.3.6.1.4.1.4242.2
# .1 %user
# .2 %nice
# .3 %system
#
# Usage:
# The following command tells to how much the fifth cpu (".4" as we start
# at 0) was busy with system calls (".3"):
# snmpwalk localhost .1.3.6.1.4.1.4242.2.3.4
#
# Changelog:
# 2006-08-24, Christian Hammers <[email protected]>
#
use strict;
use Data::Dumper;
use POSIX qw(strftime);
use Unix::Syslog qw(:macros :subs);
$|=1;
############################################################################
################################ globals ###################################
############################################################################
my $NUM_CPUS = 16; # FIXME: WATCH THIS! CHANGE THIS! AUTOMATE THIS AND SEND ME PATCH! :)
my $OID_BASE_TABLE = ".1.3.6.1.4.1.4242.2";
# This activates syslogging.
my $DEBUG = 0;
# Two dimensional array for the mpstat output.
my @mpstat;
# Used to check if a new mpstat call is necessary.
my $last_update = 0;
############################################################################
########################## misc functions ##################################
############################################################################
sub debug($) {
return if not $DEBUG;
syslog(LOG_DEBUG, "#42#DEBUG# %s", $_[0]);
}
sub output($) {
debug("out=|".$_[0]."|");
print($_[0]);
}
sub input() {
my($s) = scalar(<STDIN>);
debug("in=|$s|");
chomp($s);
return $s;
}
############################################################################
############################ main functions ################################
############################################################################
## Get all packages and their info.
sub read_mpstat() {
# Update data every 60s, quit this function else.
my $t = time();
return if ($t < $last_update + 60);
$last_update = $t;
# Save the output of "mpstat" in @mpstat;
# CPU %user %nice %system %iowait %irq %soft %idle intr/s
# 10:05:45 0 2,98 0,00 1,30 5,28 0,06 0,19 90,19 2223,00
# 10:05:45 1 19,00 0,00 13,00 0,00 0,00 4,00 64,00 1638,00
# ...
@mpstat = ();
if ( ! open(P, "LC_ALL=C mpstat -P ALL 1 1 | tail -n +5 | head -n $NUM_CPUS | awk '{ print \$3 \" \" \$4 \" \" \$5 }' | ")) {
syslog(LOG_ERR, "close: $!/$?");
die("open: $!");
}
my($line);
while (defined($line = <P>)) {
chomp($line);
my(@what) = map { int($_) } split(/ /, $line);
push(@mpstat, \@what);
}
if ( ! close(P)) {
syslog(LOG_ERR, "close: $!/$?");
die("close: $!");
}
debug("read_mpstat: read $#mpstat entries");
}
## Go through the commands sent on STDIN.
sub main_loop() {
my($line, $cmd, $oid);
LOOP: while (defined($line = input())) {
# snmpd checks if this program is alive.
if ($line =~ /^PING$/) {
output("PONG\n");
next LOOP;
} elsif ($line !~ /^(get|getnext)$/) {
syslog(LOG_ERR, "Invalid command line |$line|");
next LOOP;
}
$cmd = $1;
# Get next line from STDIN, it should be the OID number.
$oid = input();
# Update data if necessary.
read_mpstat();
# Currently we have only one base oid to work on...
if ($oid =~ /^$OID_BASE_TABLE.(\d+)(\.(\d+))?$/) {
my($what) = $1;
my($i) = $3;
# first OID suffix out of range
if (not defined $what or $what < 0 or $what > 2) {
output("NONE\n");
next LOOP;
}
# snmpwalk starts on parent OID
if (not defined $i) {
$i = 0;
}
if ($cmd eq 'get') {
if ($i <= 15) {
output("$OID_BASE_TABLE.$what.$i\ninteger\n".$mpstat[$i][$what]."\n");
} else {
output("NONE\n");
}
} elsif ($cmd eq 'getnext') {
# Remember that getnext asks for the successor of the previously given OID.
if ($i <= 14) {
$i++;
output("$OID_BASE_TABLE.$what.$i\ninteger\n".$mpstat[$i][$what]."\n");
} else {
output("NONE\n");
}
}
# OID unknown.
} else {
syslog(LOG_WARNING, "Unsupported OID $cmd |$oid|");
output("NONE\n");
next LOOP;
}
}
}
############################################################################
################################# main() ###################################
############################################################################
openlog("mpstat-snmp-plugin", 0, LOG_DAEMON);
debug("starting");
# argument and config file parsing
for (my $i=0; $ARGV[$i]; $i++) {
if ($ARGV[$i] eq '--help') {
print("Providing mpstat output as snmpd plugin.\n");
print("Usage: $0 [--help|--debug]\n");
exit(1);
} elsif ($ARGV[$i] eq '--debug') {
$DEBUG = 1;
}
}
main_loop();
debug("ending");
# vim: ts=4 expandtab
--
Christian Hammers WESTEND GmbH | Internet-Business-Provider
Technik CISCO Systems Partner - Authorized Reseller
Lütticher Straße 10 Tel 0241/701333-11
[email protected] D-52064 Aachen Fax 0241/911879
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642