#! /usr/bin/perl -w
#
# check_linux_ram plugin for nagios
#
# Check free ram & free swap on a linux local host
#
# initial version: 28 August 2004 Julien Touche
#
# Copyright Notice: GPL
# $Id: check_linux_ram.pl,v 1.0 2004/08/27 
#

use strict;
use lib "/usr/local/nagios/libexec" ;
use utils qw($TIMEOUT %ERRORS &print_revision &support);
use vars qw($PROGNAME);
my ($verbose,$cmd,$progver,$state,$state2);
my ($free,$total,$percent,$swapfree,$swaptotal,$swappercent);
my ($opt_V,$opt_h,$opt_c,$opt_w, $opt_C, $opt_W);
my ($line, @progvers);
$opt_c = $opt_w = $opt_C = $opt_W = 0;
$state = 'UNKNOWN';
$progver = '';
my $rev = '1.0';

$PROGNAME = $ARGV[0];
sub print_help ();
sub print_usage ();
sub in ($$);

$ENV{'BASH_ENV'}=''; 
$ENV{'ENV'}='';
$ENV{'PATH'}='';
$ENV{'LC_ALL'}='C';

use Getopt::Long;
Getopt::Long::Configure('bundling');
GetOptions(
	"V"   => \$opt_V,   "version"    => \$opt_V,
	"h"   => \$opt_h,   "help"       => \$opt_h,
	"w=i" => \$opt_w,   "warning=i"     => \$opt_w,
 	"c=i" => \$opt_c,   "critical=s" => \$opt_c,
	"W=i" => \$opt_W,
 	"C=i" => \$opt_C,
);

# -h means display verbose help screen
if ($opt_h) { print_help(); exit $ERRORS{'OK'}; }

# -V means display version number
if ($opt_V) { 
	print_revision($PROGNAME,"\$Revision: $rev \$ "); 
	exit $ERRORS{'OK'}; 
}

get_data();
print "$state: free RAM $percent (free=$free/total=$total) free SWAP $swappercent (free=$swapfree/total=$swaptotal| freeram=$percent;$opt_w;$opt_c;0 freeswap=$swappercent;$opt_W;$opt_C;0\n";

exit $ERRORS{$state};


########  Subroutines ==========================

# from http://www.perlmonks.org/index.pl?node_id=8781
sub round ($$) {
    sprintf "%.$_[1]f", $_[0];
}

sub get_data {
	$cmd = "/bin/cat /proc/meminfo|";
	print "$cmd\n" if ($verbose);
	open CMD, $cmd or die "Can't fork for cat: $!\n" ;

	while ( $line = <CMD> ) {
		printf "$line " if $verbose;
		chomp $line;
	
    		if ( $line =~ /^MemFree:[\s]+([0-9].*) kB/ ) {
			$free = $1;
		}
    		if ( $line =~ /^MemTotal:[\s]+([0-9].*) kB/ ) {
			$total = $1;
		}
    		if ( $line =~ /^SwapFree:[\s]+([0-9].*) kB/ ) {
			$swapfree = $1;
		}
    		if ( $line =~ /^SwapTotal:[\s]+([0-9].*) kB/ ) {
			$swaptotal = $1;
		}
	}
	close CMD;
	$percent = ($free/$total)*100;
	$percent = round $percent, 2;
	$swappercent = ($swapfree/$swaptotal)*100;
	$swappercent = round $swappercent, 2;
	#print "free=$free, total=$total, percent=$percent,\n";
	#print "free=$swapfree, total=$swaptotal, percent=$swappercent,\n";
	if ($percent > $opt_w) {
		$state = 'OK';
	} elsif ($percent < $opt_w && $percent > $opt_c) {
		$state = 'WARNING';
	} elsif ($percent < $opt_c) {
		$state = 'CRITICAL';
	}
	if ($swappercent > $opt_W) {
		$state2 = 'OK';
	} elsif ($swappercent < $opt_W && $swappercent > $opt_C) {
		$state2 = 'WARNING';
	} elsif ($swappercent < $opt_C) {
		$state2 = 'CRITICAL';
	}

	if ($state2 eq 'CRITICAL' || $state eq 'CRITICAL') {
		$state = 'CRITICAL';
	} elsif ($state2 eq 'WARNING' || $state eq 'WARNING') {
		$state = 'WARNING';
	} else {
		$state = 'OK';
	}
}


sub print_help() {
	print_revision($PROGNAME,"\$Revision: $rev \$ ");
	print "Copyright (c) 2004 Julien Touche\n";
	print "\n";
	print "Check linux free ram & free swap using /proc/meminfo\n";
	print "\n";
	print_usage();
	print "\n";
	support();
}

sub print_usage () {
	print "Usage: \n";
	print " $PROGNAME -w <warning> -c <critical> -W <warning_swap> -C <critical_swap>\n";
	print " $PROGNAME [-h | --help]\n";
	print " $PROGNAME [-V | --version]\n";
}

