# Register routine with plugin registery
$CHECKFUNCS{'vmstat'} = \&check_vmstat;

# check_vmstat is a check which gathers various values
# from vmstat commands. This plugin will attempt to gather
# the same set of stats from all platforms.
#
# No parameter level checks will be defined in this
# version. That will come in later versions

# $Id: check_vmstat,v 1.2 2002/01/17 15:41:25 sljohnson Exp $

use Spong::SafeExec qw(safe_exec);

use Config;

$VMSTAT = 'foobar';

# Try to determine which platform we are running on
# die if we don't have a platform implemented
$osname = $Config{'osname'};
if ( $osname =~ /linux|aix|dec_osf/ ) {
}

{
   $VMSTAT = '/usr/bin/vmstat 5 2', last if $osname eq 'aix';
   $VMSTAT = '/usr/bin/vmstat 5 2', last if $osname eq 'linux';
   $VMSTAT = '/usr/bin/vmstat 5 2', last if $osname eq 'dec_osf';

   # Die if we haven't implementeda given OS platform
   die('check_vmstat: $osname is a not an impletmented OS Platform')
}

sub check_vmstat {
   my( $service, $color, $summary, $message ) = ('vmstat', 'green', 'All is well. No checks yet.', '');

   my( $proc_run, $proc_block, $proc_swap, $swpd, $free, $buff, $cache,
       $si, $so, $bi, $bo, $cs, $cpu_us, $cpu_sy, $cpu_id, $mem_free );

   # Run the command
   my @msg = safe_exec($VMSTAT);

   if ($osname eq 'linux' ) {
      my $cache_line = ( $msg[0] =~ /cache/ || $msg[1] =~ /cache/ ) ? 1 : 0;

      # Stuff the last line into the line buffer
      $_ = $msg[$#msg];
      $chomp;

      if ($cache_line ) {
          if (/^(\s+\d+)(\s+\d+)(\s+\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)+\s+(\d+)\s+\d+\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*$/) 
          { 
            $proc_run = $1;  $proc_block = $2;  $proc_swap = $3;
            $swpd = $4;  $free = $5;  $buff = $6;  $cache = $7;
            $si = $8/4;  $so = $9/4;  # Convert from KB/sec to pages/sec
            $bi = $10;  $bo = $11;
            $cs = $12;
            $cpu_us = $13;  $cpu_sy = $14;  $cpu_id = $15;
            $mem_free = ($free + $buff + $cache) / 1024;  # in MB
          }
      }
      # This is for vmstat's that don't have a cache column.
      # FIX THIS: This hasn't been tested. 
      elsif ( /^(\s+\d+)(\s+\d+)(\s+\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)+\s+(\d+)\s+\d+\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*$/ ) 
      {
         $proc_run = $1;  $proc_block = $2;  $proc_swap = $3;
         $swpd = $4;  $free = $5;  $buff = $6; 
         $si = $7/4;  $so = $8/4;  # Convert from KB/sec to pages/sec
         $bi = $9;  $bo = $10;
         $cs = $11;
         $cpu_us = $12;  $cpu_sy = $13;  $cpu_id = $13;
         $mem_free = ($free + $buff) / 1024;  # in MB
      }

      $message =
         "mem_free = $mem_free\n" .
         "proc_run = $proc_run\n" . 
         "proc_block = $proc_block\n" . 
         "si = $si\n" . 
         "so = $so\n" . 
         "cs = $cs\n" . 
         "cpu_us = $cpu_us\n" . 
         "cpu_sy = $cpu_sy\n" . 
         "cpu_id = $cpu_id\n";

      # Extract page in and page out from /proc/stat for linux
      my( $sleep ) = 5;
      my ($opi, $opo, $pi, $po) = (0,0,0,0);


      # Grab the paging counts
      my @pmsg = safe_exec('cat /proc/stat');
      while ($_ =  shift @pmsg) {
         if ( /^page\s+(\d+)\s+(\d+)/ ) {
            ($opi, $opo) = ($1, $2);
            last;
         }
      }
      sleep(5); # Pause a bit
      # Grab the paging counts again.
      @pmsg = safe_exec('cat /proc/stat');
      while ($_ = shift @pmsg) {
         if ( /^page\s+(\d+)\s+(\d+)/ ) {
            ($pi, $po) = ($1, $2);
            last;
         }
      }

      # Now calculate the paging rate from the two set of counts
      $pi -= $opi; $pi = int(($pi / $sleep) + 0.5);
      $po -= $opo; $po = int(($po / $sleep) + 0.5);

      $message = $message . "pi = $po\npo = $po\n";

      $message = $message . "Command output:\n" . join('',@msg);

   }   
   elsif ($osname eq 'aix') {
      # Stuff the last line into the line buffer
      $_ = $msg[$#msg];
      $chomp;
      if (/^\s*(\d+)\s+(..)\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+.+\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*$/)
       { 
         my ($avm);
         $proc_run = $1;  $proc_block = $2;
         $avm = $3;  $free = $3;
         $pi = $6;   $po = $7;
         $cs = $8;
         # cpu wait is included in cpu_sy
         $cpu_us = $9;  $cpu_sy = $10+$12;  $cpu_id = $11; 
         $mem_free = ($free * 4 )/1000 ;  # convert to MB, 1 page = 4K
      }

      $message =
         "mem_free = $mem_free\n" .
         "proc_run = $proc_run\n" . 
         "proc_block = $proc_block\n" . 
#         "si = 0\n" .     # AIX doesn't swap
#         "so = 0\n" . 
         "pi = $pi\n" . 
         "po = $po\n" . 
         "cs = $cs\n" . 
         "cpu_us = $cpu_us\n" . 
         "cpu_sy = $cpu_sy\n" . 
         "cpu_id = $cpu_id\n";

      $message = $message . "Command output:\n" . join('',@msg);

#      main::debug("check_vmstat:  message  = \n$message");
   }
   elsif ( $osname eq 'dec_osf' ) {
      # Stuff the last line into the line buffer
      $_ = $msg[$#msg];
      $chomp;
 	if (/^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+[KM]?)\s+(\d+[KM]?)\s+(\d+[KM]?)\s+(\d+[KM]?)\s+(\d+[KM]?)\s+(\d+[KM]?)\s+(\d+[KM]?)\s+(\d+[KM]?)\s+(\d+[KM]?)\s+(\d+)\s+(\d+[KM]?)\s+(\d+[KM]?)\s+(\d+)\s+(\d+)\s+(\d+)/ )
       { 
         my($t);
         $proc_run = $1;  $proc_block = $2; 
         $free = $5;
         $pi = $11;   $po = $12;
         $cs = $15;
         if ($cs =~ /(\d+)K/) { $cs = $1 * 1000; }
         # cpu wait is included in cpu_sy
         $cpu_us = $16;  $cpu_sy = $17;  $cpu_id = $18; 
         $free =~ m/(\d+)([KM]*)/; ($mem_free,$t) = ($1,$2);
         $mem_free = $mem_free * 1000 if $t eq 'K';
         $mem_free = ($mem_free * 8 )/1000 ;  # convert to MB, 1 page = 8K
      }

      $message =
         "mem_free = $mem_free\n" .
         "proc_run = $proc_run\n" . 
         "proc_block = $proc_block\n" . 
#         "si = 0\n" .     # AIX doesn't swap
#         "so = 0\n" . 
         "pi = $pi\n" . 
         "po = $po\n" . 
         "cs = $cs\n" . 
         "cpu_us = $cpu_us\n" . 
         "cpu_sy = $cpu_sy\n" . 
         "cpu_id = $cpu_id\n";

      $message = $message . "Command output:\n" . join('',@msg);

#      main::debug("check_vmstat:  message  = \n$message");
   }
   
   &debug("check_vmstat - $color, $summary");
   &status( $SPONGSERVER, $HOST, $service, $color, $summary, $message );

}


# I'm included perl code, I need this line.
1;

