#!/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 CPU 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.3";

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 -f /var/log/sa/sa.%04d_%02d_%02d | /usr/bin/tail -n 2", $year, $month, $day); 
}
else {
   $cmd = '/usr/bin/sar | /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 ($_ =~ /LINUX RESTART/) {
     print "LINUX RESTART ... please wait for next service check!\n";
     exit $ERRORS{'OK'};
  }
  my @meminfo = split(/\s+/, $_);

  my $prefix = '';
  if ($_ =~ /^Average/) { $prefix = 'avg_'; }

  $extracted_info{$prefix . 'idle'}   = $meminfo[$#meminfo];
  $extracted_info{$prefix . 'system'} = $meminfo[$#meminfo-1];
  $extracted_info{$prefix . 'nice'}   = $meminfo[$#meminfo-2];
  $extracted_info{$prefix . 'user'}   = $meminfo[$#meminfo-3];
}

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


my ($cpu_usage, $avg_cpu_usage) = undef;
if ($extracted_info{'idle'} !~ /(\d+)|(\d+\.\d+)/) {
   #-- take the average value instead the actual one
   if ($extracted_info{'avg_idle'} =~ /(\d+)|(\d+\.\d+)/) {
      $cpu_usage     = 100 - $extracted_info{'avg_idle'};
      $avg_cpu_usage = $cpu_usage;
   }
   else {
      print "ERROR: unexpected command output (idle: $extracted_info{'idle'}, avg_idle: $extracted_info{'avg_idle'})\n";
      exit $ERRORS{'UNKNOWN'};
   }
}
else {
   #-- normal behaviour: calculate usage from fetched values!
   $cpu_usage     = 100 - $extracted_info{'idle'};
   $avg_cpu_usage = 100 - $extracted_info{'avg_idle'};
}

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




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

Perl Netsaint Plugin for checking CPU 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'};
}
