#!/usr/bin/perl -w
#
# Author: Christian Timmerer <timse@itec.uni-klu.ac.at>
# Date  : 31.07.2001
#
# Desription: Uses sar from sysstat package to determine memory usage
#
# 01.08.2001, Christian Timmerer
#		added little hack for midnight - using information from
#		previous day! requires Time::localtime and Date::Calc
#
# ----------------------------------------------------------------------
#
# 03.08.2001, Christian Timmerer
#               some error handling routines added!
#
#
#
# Copyright Notice: GPL
#
BEGIN {
        if ($0 =~ m/^(.*?)[\/\\]([^\/\\]+)$/) {
                $runtimedir = $1;
                $PROGNAME = $2;
        }
}

use strict;
use lib $main::runtimedir;
use Getopt::Long;
use vars qw($VERSION $PROGNAME);
use utils qw($TIMEOUT %ERRORS &print_revision &support);
use Getopt::Long;
Getopt::Long::Configure('bundling', 'no_ignore_case');
use Time::localtime;
use Date::Calc qw(Add_Delta_Days);

$VERSION = "0.0.2";

sub print_help ();
sub print_usage ();
sub help ();
sub version ();

delete @ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

my $p_warn = 80;
my $p_crit = 90;

my %options = ();
my $err = GetOptions(
	"V|version"	=> \$options{version},
	"h|help"	=> \$options{help},
	"w|warning=i"	=> \$options{p_warn},
	"c|critical=i"	=> \$options{p_crit},
	);

if ($err != 1) { print_usage(); exit $ERRORS{'UNKNOWN'}; }
if ($options{version}) { version(); }
if ($options{help})    { help(); }


if ($options{p_warn}) { $p_warn = $options{p_warn}; }
if ($options{p_crit}) { $p_crit = $options{p_crit}; }
if ($p_warn > $p_crit) {
   print "Warning threshold ($p_warn) greater than critical ($p_crit)\n";
   exit $ERRORS{'UNKNOWN'};
}

my $time = localtime;

my $cmd;
if ($time->hour == 0 && ($time->min >= 0 && $time->min <= 5)) {
   my ($year, $month, $day) = Add_Delta_Days($time->year+1900, $time->mon+1, $time->mday, -1);
   $cmd = sprintf("/usr/bin/sar -r -f /var/log/sa/sa.%04d_%02d_%02d | /usr/bin/tail -n 2", $year, $month, $day);
}
else {
   $cmd = '/usr/bin/sar -r | /usr/bin/tail -n 2';
}

my @info = qx/$cmd/;

if (! scalar @info) {
   print "No output returned from $cmd\n";
   exit $ERRORS{'UNKNOWN'};
}

my %extracted_info = ();
foreach (@info) {
  chomp;
  if (! length($_)) {
     print "ERROR: Nothing returned from command ($cmd)\n";
     exit $ERRORS{'UNKNOWN'};
  }
  if ($_ =~ /LINUX RESTART/) {
     print "LINUX RESTART ... please wait for next service check!\n";
     exit $ERRORS{'OK'};
  }
  my @meminfo = split(/\s+/, $_);

  for (my $i=$#meminfo; $i > 0; $i--) {
      if ($meminfo[$i] !~ /(\d+)|(\d+\.\d+)/) {
         print "ERROR: unexpected command output ($meminfo[$i])\n";
	 exit $ERRORS{'UNKNOWN'};
      }
  }
  my $prefix = '';
  if ($_ =~ /^Average/) { $prefix = 'avg_'; }

  $extracted_info{$prefix . 'swpused'}   = $meminfo[$#meminfo];
  $extracted_info{$prefix . 'kbswpused'} = $meminfo[$#meminfo-1];
  $extracted_info{$prefix . 'kbswpfree'} = $meminfo[$#meminfo-2];
  $extracted_info{$prefix . 'kbcached'}  = $meminfo[$#meminfo-3];
  $extracted_info{$prefix . 'kbbuffers'} = $meminfo[$#meminfo-4];
  $extracted_info{$prefix . 'kbmemshrd'} = $meminfo[$#meminfo-5];
  $extracted_info{$prefix . 'memused'}   = $meminfo[$#meminfo-6];
  $extracted_info{$prefix . 'kbmemused'} = $meminfo[$#meminfo-7];
  $extracted_info{$prefix . 'kbmemfree'} = $meminfo[$#meminfo-8];
}

#foreach (sort keys %extracted_info) {
#  print "$_\t= $extracted_info{$_}\n";
#}

my $mem_total = $extracted_info{'kbmemfree'} + $extracted_info{'kbmemused'};
my $mem_used = $extracted_info{'kbmemused'} - $extracted_info{'kbbuffers'} - $extracted_info{'kbcached'};
my $avg_mem_used = $extracted_info{'avg_kbmemused'} - $extracted_info{'avg_kbbuffers'} - $extracted_info{'avg_kbcached'};

my $mem_usage = sprintf("%.2f", $mem_used * 100 / $mem_total);
my $avg_mem_usage = sprintf("%.2f", $avg_mem_used * 100 / $mem_total);

if ($mem_usage > $p_crit) {
   print "Memory usage greater than critical threshold value ($mem_usage > $p_crit)\n";
   exit $ERRORS{'CRITICAL'};
}
elsif ($mem_usage > $p_warn) {
   print "Memory usage greater than warning threshold value ($mem_usage > $p_warn)\n";
   exit $ERRORS{'WARNING'};
}
else {
   print "Memory usage (%): $mem_usage (Average: $avg_mem_usage)\n";
   exit $ERRORS{'OK'};
}




sub print_help() {
        print_revision($PROGNAME,'$Revision: 1.2' . $VERSION . ' $ ');
        print <<HELP;

Perl Netsaint Plugin for checking memory Usage

Copyright (c) 2001 Christian Timmerer <timse\@itec.uni-klu.ac.a.t>

Usage: $PROGNAME [options]

Options:
  -w | --warning=RANGE	Warning threshold for memory usage in percent
  -c | --critical=RANGE	Critical threshold for memory usage in percent

  -h | --help		this message
  -v | --version	Version information

HELP
        support();
}

sub print_usage () {
        print "$PROGNAME -H host [-w warn -c crit]\n";
        print "$PROGNAME [-h | --help]\n";
        print "$PROGNAME [-V | --version]\n";
}

sub version () {
        print_revision($PROGNAME,'$Revision: 1.2' . $VERSION . ' $ ');
        exit $ERRORS{'OK'};
}

sub help () {
        print_help();
        exit $ERRORS{'OK'};
}
