3
# Heavily based on the script from:
4
# check_mem.pl Copyright (C) 2000 Dan Larsson <dl@tyfon.net>
6
# Justin Ellison <justin@techadvise.com>
8
# The MIT License (MIT)
9
# Copyright (c) 2011 justin@techadvise.com
11
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
12
# software and associated documentation files (the "Software"), to deal in the Software
13
# without restriction, including without limitation the rights to use, copy, modify,
14
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
15
# permit persons to whom the Software is furnished to do so, subject to the following conditions:
17
# The above copyright notice and this permission notice shall be included in all copies
18
# or substantial portions of the Software.
20
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23
# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
24
# OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
# OTHER DEALINGS IN THE SOFTWARE.
27
# Tell Perl what we need to use
31
#TODO - Convert to Nagios::Plugin
34
# Predefined exit codes for Nagios
35
use vars qw($opt_c $opt_f $opt_u $opt_w $opt_C $opt_v %exit_codes);
36
%exit_codes = ('UNKNOWN' ,-1,
42
# Get our variables, do our checking:
46
my ($free_memory_kb,$used_memory_kb,$caches_kb) = get_memory_info();
47
print "$free_memory_kb Free\n$used_memory_kb Used\n$caches_kb Cache\n" if ($opt_v);
49
if ($opt_C) { #Do we count caches as free?
50
$used_memory_kb -= $caches_kb;
51
$free_memory_kb += $caches_kb;
54
# Round to the nearest KB
55
$free_memory_kb = sprintf('%d',$free_memory_kb);
56
$used_memory_kb = sprintf('%d',$used_memory_kb);
57
$caches_kb = sprintf('%d',$caches_kb);
59
# Tell Nagios what we came up with
60
tell_nagios($used_memory_kb,$free_memory_kb,$caches_kb);
64
my ($used,$free,$caches) = @_;
66
# Calculate Total Memory
67
my $total = $free + $used;
68
print "$total Total\n" if ($opt_v);
70
my $perfdata = "|TOTAL=${total}KB;;;; USED=${used}KB;;;; FREE=${free}KB;;;; CACHES=${caches}KB;;;;";
73
my $percent = sprintf "%.1f", ($free / $total * 100);
74
if ($percent <= $opt_c) {
75
finish("CRITICAL - $percent% ($free kB) free!$perfdata",$exit_codes{'CRITICAL'});
77
elsif ($percent <= $opt_w) {
78
finish("WARNING - $percent% ($free kB) free!$perfdata",$exit_codes{'WARNING'});
81
finish("OK - $percent% ($free kB) free.$perfdata",$exit_codes{'OK'});
85
my $percent = sprintf "%.1f", ($used / $total * 100);
86
if ($percent >= $opt_c) {
87
finish("CRITICAL - $percent% ($used kB) used!$perfdata",$exit_codes{'CRITICAL'});
89
elsif ($percent >= $opt_w) {
90
finish("WARNING - $percent% ($used kB) used!$perfdata",$exit_codes{'WARNING'});
93
finish("OK - $percent% ($used kB) used.$perfdata",$exit_codes{'OK'});
100
print "\ncheck_mem.pl v1.0 - Nagios Plugin\n\n";
102
print " check_mem.pl -<f|u> -w <warnlevel> -c <critlevel>\n\n";
104
print " -f Check FREE memory\n";
105
print " -u Check USED memory\n";
106
print " -C Count OS caches as FREE memory\n";
107
print " -w PERCENT Percent free/used when to warn\n";
108
print " -c PERCENT Percent free/used when critical\n";
109
print "\nCopyright (C) 2000 Dan Larsson <dl\@tyfon.net>\n";
110
print "check_mem.pl comes with absolutely NO WARRANTY either implied or explicit\n";
111
print "This program is licensed under the terms of the\n";
112
print "MIT License (check source code for details)\n";
113
exit $exit_codes{'UNKNOWN'};
116
sub get_memory_info {
117
my $used_memory_kb = 0;
118
my $free_memory_kb = 0;
119
my $total_memory_kb = 0;
123
if ( -e '/usr/bin/uname') {
124
$uname = `/usr/bin/uname -a`;
126
elsif ( -e '/bin/uname') {
127
$uname = `/bin/uname -a`;
130
die "Unable to find uname in /usr/bin or /bin!\n";
132
print "uname returns $uname" if ($opt_v);
133
if ( $uname =~ /Linux/ ) {
134
my @meminfo = `/bin/cat /proc/meminfo`;
137
if (/^Mem(Total|Free):\s+(\d+) kB/) {
138
my $counter_name = $1;
139
if ($counter_name eq 'Free') {
140
$free_memory_kb = $2;
142
elsif ($counter_name eq 'Total') {
143
$total_memory_kb = $2;
146
elsif (/^(Buffers|Cached|SReclaimable):\s+(\d+) kB/) {
150
$used_memory_kb = $total_memory_kb - $free_memory_kb;
152
elsif ( $uname =~ /SunOS/ ) {
153
eval "use Sun::Solaris::Kstat";
154
if ($@) { #Kstat not available
156
print "You can't report on Solaris caches without Sun::Solaris::Kstat available!\n";
157
exit $exit_codes{UNKNOWN};
159
my @vmstat = `/usr/bin/vmstat 1 2`;
165
$free_memory_kb = (split(/ /,$line))[5] / 1024;
166
my @prtconf = `/usr/sbin/prtconf`;
168
if (/^Memory size: (\d+) Megabytes/) {
169
$total_memory_kb = $1 * 1024;
172
$used_memory_kb = $total_memory_kb - $free_memory_kb;
175
else { # We have kstat
176
my $kstat = Sun::Solaris::Kstat->new();
177
my $phys_pages = ${kstat}->{unix}->{0}->{system_pages}->{physmem};
178
my $free_pages = ${kstat}->{unix}->{0}->{system_pages}->{freemem};
179
# We probably should account for UFS caching here, but it's unclear
180
# to me how to determine UFS's cache size. There's inode_cache,
181
# and maybe the physmem variable in the system_pages module??
182
# In the real world, it looks to be so small as not to really matter,
183
# so we don't grab it. If someone can give me code that does this,
184
# I'd be glad to put it in.
185
my $arc_size = (exists ${kstat}->{zfs} && ${kstat}->{zfs}->{0}->{arcstats}->{size}) ?
186
${kstat}->{zfs}->{0}->{arcstats}->{size} / 1024
188
$caches_kb += $arc_size;
189
my $pagesize = `pagesize`;
191
$total_memory_kb = $phys_pages * $pagesize / 1024;
192
$free_memory_kb = $free_pages * $pagesize / 1024;
193
$used_memory_kb = $total_memory_kb - $free_memory_kb;
196
elsif ( $uname =~ /AIX/ ) {
197
my @meminfo = `/usr/bin/vmstat -v`;
200
if (/^\s*([0-9.]+)\s+(.*)/) {
201
my $counter_name = $2;
202
if ($counter_name eq 'memory pages') {
203
$total_memory_kb = $1*4;
205
if ($counter_name eq 'free pages') {
206
$free_memory_kb = $1*4;
208
if ($counter_name eq 'file pages') {
213
$used_memory_kb = $total_memory_kb - $free_memory_kb;
217
print "You can't report on $uname caches!\n";
218
exit $exit_codes{UNKNOWN};
220
my $command_line = `vmstat | tail -1 | awk '{print \$4,\$5}'`;
222
my @memlist = split(/ /, $command_line);
224
# Define the calculating scalars
225
$used_memory_kb = $memlist[0]/1024;
226
$free_memory_kb = $memlist[1]/1024;
227
$total_memory_kb = $used_memory_kb + $free_memory_kb;
229
return ($free_memory_kb,$used_memory_kb,$caches_kb);
241
# Shortcircuit the switches
242
if (!$opt_w or $opt_w == 0 or !$opt_c or $opt_c == 0) {
243
print "*** You must define WARN and CRITICAL levels!\n";
246
elsif (!$opt_f and !$opt_u) {
247
print "*** You must select to monitor either USED or FREE memory!\n";
251
# Check if levels are sane
252
if ($opt_w <= $opt_c and $opt_f) {
253
print "*** WARN level must not be less than CRITICAL when checking FREE memory!\n";
256
elsif ($opt_w >= $opt_c and $opt_u) {
257
print "*** WARN level must not be greater than CRITICAL when checking USED memory!\n";
263
my ($msg,$state) = @_;