This Perl 5 script (I can it "netapp") can be used to remotely monitor a Network Appliance via SNMP. To use it, you need a working version of "snmpwalk" and "snmpget" from the UCD snmp tools distribution in addition to version 1.1 of the NetApp MIB. I might switch it over to using the Perl5 SNMP module eventually. You'll possibly have to change some paths and parsing depending on how different your SNMP tools installation is from ours.
I wrote this to allow non-privileged users to get information from the toaster without logging in or running rsh. These are the basic commands supported:
partial sysstat -> "netapp -sysstat filer" or "netapp -sysstat=60 filer" df -> "netapp -df filer" df -i -> "netapp -if filer" also -> "netapp -df -if filer"
It's pretty intelligent about loading the network too. An earlier version of this script only used snmpwalk, which produces a lot of back-and-forth chatter, even if you walk a very small portion of the SNMP tree.
Example output:
$ netapp -sysstat myf330 CPU NFS Net kB/s in out 35% 411 675 915 16% 164 230 153
$ netapp -df myf630 Filesystem kbytes used avail capacity Mounted on / 78277988 54447172 23830816 70% / /.snapshot 8697552 19281448 -10583896 222% /.snapshot
$ netapp -if myf630 Filesystem iused ifree %iused Mounted on / 694555 2174415 24% /
I hope this is useful to someone...
Dan
------- start of cut text -------------- #!/usr/local/bin/perl # please do not post this script to Usenet, I do not like spam.
# Copyright (C) 1997 Transmeta Corporation # written by Daniel Quinlan quinlan@transmeta.com # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$ENV{'PATH'} = "/usr/local/bin:/usr/bin:/bin"; $ENV{'MIBFILE'} = "/usr/local/share/snmp/mibs/netapp.mib";
$prog = $0; $prog =~ s@.*/@@;
use Getopt::Long; &GetOptions("help", "dump", "sysstat:i", "df", "if", "quota");
if ($opt_help) { &usage; exit 0; }
if ($ARGV[0]) { $host = $ARGV[0]; } else { &usage; exit 1; }
sub usage { print <<EOF; usage: $prog [options] filer --help print this help --sysstat=n report filer statistics every n seconds (15 is default) --df summarize free disk space --if summarize inode use --quota (unimplemented) report quotas EOF }
if (defined ($opt_sysstat)) { my $interval = 15; my $count = 0; my $first = 1; my $query = join(' ', "cpu.cpuUpTime.0", "cpu.cpuBusyTime.0", "misc.miscNfsOps.0", "misc.miscNfsOps.0", "misc.miscNetRcvdKB.0", "misc.miscNetSentKB.0");
$ENV{'PREFIX'} = ".iso.org.dod.internet.private.enterprises.netapp.netapp1.sysStat";
if ($opt_sysstat) { $interval = $opt_sysstat; if ($interval < 1) { die("$prog: sysstat interval must be greater than 0\n"); } }
for (;;) { if ($count-- == 0) { print " CPU NFS Net kB/s\n"; print " in out\n"; $count = 20; }
open (SNMPGET, "snmpget -v 1 $host public $query |"); while (<SNMPGET>) { /cpuUpTime.0 = Timeticks: ((\d+))/ && ($cpuUpTime2 = $1); /cpuBusyTime.0 = Timeticks: ((\d+))/ && ($cpuBusyTime2 = $1); /miscNfsOps.0 = (\d+)/ && ($miscNfsOps2 = $1); /miscNetRcvdKB.0 = (\d+)/ && ($miscNetRcvdKB2 = $1); /miscNetSentKB.0 = (\d+)/ && ($miscNetSentKB2 = $1); } close (SNMPGET);
if ($first) { $first = 0; } else { $cpu = int (($cpuBusyTime2 - $cpuBusyTime1) / ($cpuUpTime2 - $cpuUpTime1) * 100); $NfsOps = int (($miscNfsOps2 - $miscNfsOps1) / $interval);
# work-around if ($miscNetRcvdKB2 < $miscNetRcvdKB1) { $miscNetRcvdKB1 -= (2**32 / 1024); } if ($miscNetSentKB2 < $miscNetSentKB1) { $miscNetSentKB1 -= (2**32 / 1024); } $NetIn = int (($miscNetRcvdKB2 - $miscNetRcvdKB1) / $interval); $NetOut = int (($miscNetSentKB2 - $miscNetSentKB1) / $interval);
printf "%3d%% %6d %5d %5d\n", $cpu, $NfsOps, $NetIn, $NetOut; }
$cpuBusyTime1 = $cpuBusyTime2; $cpuUpTime1 = $cpuUpTime2; $miscNfsOps1 = $miscNfsOps2; $miscNetRcvdKB1 = $miscNetRcvdKB2; $miscNetSentKB1 = $miscNetSentKB2;
sleep $interval; } }
if ($opt_dump) { open (SNMPWALK, "snmpwalk -v 1 $host public netapp |"); while (<SNMPWALK>) { print $_; } close (SNMPWALK);
}
if ($opt_df || $opt_if) { my $min, $max, $i; my $query = "";
$ENV{'PREFIX'} = ".iso.org.dod.internet.private.enterprises.netapp.netapp1.filesys.dfTable.dfEntry";
open (SNMPWALK, "snmpwalk -v 1 $host public dfIndex |"); while (<SNMPWALK>) { /dfTable.dfEntry.dfIndex.(\d+) = (\d+)/ && do { $dfIndex[$1] = $2; if (!defined($min)) { $min = $1; } $max = $1; }; } close (SNMPWALK);
for ($i = $min; $i <= $max; $i++) { $query .= join(' ', "dfEntry.dfFileSys.$i", "dfEntry.dfKBytesTotal.$i", "dfEntry.dfKBytesUsed.$i", "dfEntry.dfKBytesAvail.$i", "dfEntry.dfPerCentKBytesCapacity.$i", "dfEntry.dfInodesUsed.$i", "dfEntry.dfInodesFree.$i", "dfEntry.dfPerCentInodeCapacity.$i", "dfEntry.dfMountedOn.$i "); } $query =~ s/ $//;
$ENV{'PREFIX'} = ".iso.org.dod.internet.private.enterprises.netapp.netapp1.filesys.dfTable";
open (SNMPGET, "snmpget -v 1 $host public $query |"); while (<SNMPGET>) { /dfFileSys.(\d+) = "(\S+)"/ && ($dfFileSys[$1] = $2); /dfKBytesTotal.(\d+) = (\d+)/ && ($dfKBytesTotal[$1] = $2); /dfKBytesUsed.(\d+) = (\d+)/ && ($dfKBytesUsed[$1] = $2); /dfKBytesAvail.(\d+) = (-?\d+)/ && ($dfKBytesAvail[$1] = $2); /dfPerCentKBytesCapacity.(\d+) = (\d+)/ && ($dfPerCentKBytesCapacity[$1] = $2); /dfInodesUsed.(\d+) = (\d+)/ && ($dfInodesUsed[$1] = $2); /dfInodesFree.(\d+) = (\d+)/ && ($dfInodesFree[$1] = $2); /dfPerCentInodeCapacity.(\d+) = (\d+)/ && ($dfPerCentInodeCapacity[$1] = $2); /dfMountedOn.(\d+) = "(\S+)"/ && ($dfMountedOn[$1] = $2); } close (SNMPGET);
if ($opt_df) { print "Filesystem kbytes used avail capacity Mounted on\n"; for ($i = $min; $i <= $max; $i++) { printf "%-10s %10d %10d %10d %3d%% %s\n", $dfFileSys[$i], $dfKBytesTotal[$i], $dfKBytesUsed[$i], $dfKBytesAvail[$i], $dfPerCentKBytesCapacity[$i], $dfMountedOn[$i]; } } if ($opt_if) { print "Filesystem iused ifree %iused Mounted on\n"; printf "%-10s %10d %10d %3d%% %s\n", $dfFileSys[1], $dfInodesUsed[1], $dfInodesFree[1], $dfPerCentInodeCapacity[1], $dfMountedOn[1]; } } ------- end ----------------------------