The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/local/bin/perl -w

=pod

=head1 NAME

swap.monitor - monitor swap space usage via SNMP

=head1 SYNOPSIS

swap.monitor [ --community=community ] [ --percent=p ] host [...]

=head1 ARGUMENTS

=over 4

=item --community=community

SNMP community (default=public)

=item --percent=p

The monitor is deemed to fail if swap space utilisation is >= p
(default=75).

=item host [...]

Space separated list of hosts to monitor.

=back

=head1 DESCRIPTION

B<swap.monitor> monitors swap space usage via the UCSD SNMP agent.  It
is designed to be used as a monitor for the B<mon> package.  As such
if any host's swap utilisation is >= a particular percentage it will
return 1 and output the hostnames that failed and the percentage of
the swap in use.  If all hosts meet the utilisation criteria 0 is
returned.

The swap space statistics must be collected from an extension to the
SNMP agent named 'swap' which returns the percentage of swap space in
use.

=head1 BUGS

The swap statistics should really be collected from a MIB but there
didn't seem to be one which worked for Linux and Solaris.

=head1 SEE ALSO

F<swap.ext> - snmp agent extenstion for monitoring swap space
I<http://consult.ml.org/~trockij/mon/>
I<http://www.ece.ucdavis.edu/ucd-snmp/>

=head1 AUTHOR

Paul Sharpe E<lt>paul@miraclefish.comE<gt>

=head1 COPYRIGHT

Copyright (c) 1998 Paul Sharpe. England.  All rights reserved.  This
program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=cut

use Pod::Usage;
use SNMP;
use Getopt::Long;

$opt_community = $opt_percent = undef;
pod2usage("") unless GetOptions("community=s","percent=i");
pod2usage("") unless @ARGV;
$community = $opt_community || 'public';
$percent   = $opt_percent   || 75;

# don't load the whole mib
# enterprises.ucdavis.extTable.extEntry.extNames
$extNames = '.1.3.6.1.4.1.2021.8.1.2';
# enterprises.ucdavis.extTable.extEntry.extOutput
$extOutput = '.1.3.6.1.4.1.2021.8.1.101';
$ENV{'MIBS'} = '';
$SNMP::use_long_names = 1;

for $host (@ARGV) {
  $session = new SNMP::Session(DestHost => $host,
			       Community => $community);
  $var = new SNMP::Varbind([$extNames]);

  $match = 0;
  for($swap = $session->getnext($var);
      $var->tag =~ /$extNames/          # still in table
      and not $session->{ErrorStr};     # and not end of mib or other error
      $swap = $session->getnext($var)
     ) {
    $match = 1, last if $swap eq 'swap';
  }

  if ( $session->{ErrorNum} ) {
    push(@failures,"$host $session->{ErrorStr}");
  } elsif ( $match ) {
    my($suffix) = $var->tag =~ /\.(\d+)$/;
    my $var     = new SNMP::Varbind(["$extOutput.$suffix"]);
    my $p       = $session->get($var);
    push(@failures,"$host swap space is $p% full") if $p >= $percent;
  } else {
    push(@failures,"$host SNMP agent isn't monitoring swap space");
  }
  
}

if (@failures) {
  print join (", ", @failures), "\n";
  exit 1;
}

exit 0;