#!/usr/local/bin/perl # $Id: check_mem.pl,v 1.1.1.1 2007/11/13 05:25:13 hmann Exp $ # check_mem.pl Copyright (C) 2000 Dan Larsson # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # you should have received a copy of the GNU General Public License # along with this program (or with Nagios); if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA # Tell Perl what we need to use use strict; use warnings; use Getopt::Std; use vars qw($opt_c $opt_f $opt_u $opt_w $free_memory $used_memory $total_memory $crit_level $warn_level %exit_codes @memlist $percent $fmt_pct $verb_err $sysctl $sysctl_output); # Predefined exit codes for Nagios %exit_codes = ('UNKNOWN' ,-1, 'OK' , 0, 'WARNING' , 1, 'CRITICAL', 2,); # Turn this to 1 to see reason for parameter errors (if any) $verb_err = 0; # query the system through the generic sysctl(8) interface # (this does not require special priviledges) $sysctl = {}; $sysctl_output = `/sbin/sysctl -a`; foreach my $line (split(/\n/, $sysctl_output)) { if ($line =~ m/^([^:]+):\s+(.+)\s*$/s) { $sysctl->{$1} = $2; } } my $mem_active = $sysctl->{"vm.stats.vm.v_active_count"} * $sysctl->{"hw.pagesize"}; my $mem_inactive = $sysctl->{"vm.stats.vm.v_inactive_count"} * $sysctl->{"hw.pagesize"}; my $mem_cache = $sysctl->{"vm.stats.vm.v_cache_count"} * $sysctl->{"hw.pagesize"}; my $mem_free = $sysctl->{"vm.stats.vm.v_free_count"} * $sysctl->{"hw.pagesize"}; # Define the calculating scalars $free_memory = $mem_inactive + $mem_cache + $mem_free; $total_memory = &mem_rounded($sysctl->{"hw.physmem"}); $used_memory = $total_memory - $free_memory; # Get the options if ($#ARGV le 0) { &usage; } else { getopts('c:fuw:'); } # Shortcircuit the switches if (!$opt_w or $opt_w == 0 or !$opt_c or $opt_c == 0) { print "*** You must define WARN and CRITICAL levels!" if ($verb_err); &usage; } elsif (!$opt_f and !$opt_u) { $opt_u = 1; # print "*** You must select to monitor either USED or FREE memory!" if ($verb_err); # &usage; } # Check if levels are sane if ($opt_w <= $opt_c and $opt_f) { print "*** WARN level must not be less than CRITICAL when checking FREE memory!" if ($verb_err); &usage; } elsif ($opt_w >= $opt_c and $opt_u) { print "*** WARN level must not be greater than CRITICAL when checking USED memory!" if ($verb_err); &usage; } $warn_level = $opt_w; $crit_level = $opt_c; if ($opt_f) { $percent = $free_memory / $total_memory * 100; $fmt_pct = sprintf "%.1f", $percent; if ($percent <= $crit_level) { print "Memory CRITICAL - $fmt_pct% ($free_memory kB) free |pct=$fmt_pct\n"; exit $exit_codes{'CRITICAL'}; } elsif ($percent <= $warn_level) { print "Memory WARNING - $fmt_pct% ($free_memory kB) free |pct=$fmt_pct\n"; exit $exit_codes{'WARNING'}; } else { print "Memory OK - $fmt_pct% ($free_memory kB) free |pct=$fmt_pct\n"; exit $exit_codes{'OK'}; } } elsif ($opt_u) { $percent = $used_memory / $total_memory * 100; $fmt_pct = sprintf "%.1f", $percent; if ($percent >= $crit_level) { print "Memory CRITICAL - $fmt_pct% ($used_memory kB) used |pct=$fmt_pct\n"; exit $exit_codes{'CRITICAL'}; } elsif ($percent >= $warn_level) { print "Memory WARNING - $fmt_pct% ($used_memory kB) used |pct=$fmt_pct\n"; exit $exit_codes{'WARNING'}; } else { print "Memory OK - $fmt_pct% ($used_memory kB) used |pct=$fmt_pct\n"; exit $exit_codes{'OK'}; } } # round the physical memory size to the next power of two which is # reasonable for memory cards. We do this by first determining the # guessed memory card size under the assumption that usual computer # hardware has an average of a maximally eight memory cards installed # and those are usually of equal size. sub mem_rounded { my ($mem_size) = @_; my $chip_size = 1; my $chip_guess = ($mem_size / 8) - 1; while ($chip_guess != 0) { $chip_guess >>= 1; $chip_size <<= 1; } my $mem_round = (int($mem_size / $chip_size) + 1) * $chip_size; return $mem_round; } # Show usage sub usage() { print "\ncheck_mem.pl v1.0 - Nagios Plugin\n\n"; print "usage:\n"; print " check_mem.pl - -w -c \n\n"; print "options:\n"; print " -f Check FREE memory\n"; print " -u Check USED memory\n"; print " -w PERCENT Percent free/used when to warn\n"; print " -c PERCENT Percent free/used when critical\n"; print "\nCopyright (C) 2000 Dan Larsson \n"; print "check_mem.pl comes with absolutely NO WARRANTY either implied or explicit\n"; print "This program is licensed under the terms of the\n"; print "GNU General Public License (check source code for details)\n"; exit $exit_codes{'UNKNOWN'}; }