3 # check_mem_ucd_snmp: nagios-check testing the memory of a linux-system via SNMP
5 # see http://www.intra2net.com/en/developer/monitoring/
6 # for current version, documentation, contact information etc.
8 # (C) 2009 by Gerd v. Egidy <gerd.von.egidy@intra2net.com>
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
26 ############ basic plugin data & argument handling ############
27 my $np = Nagios::Plugin->new(
28 plugin => "check_mem_ucd_snmp",
30 blurb => "nagios-check testing the memory of a linux-system via SNMP",
31 usage => "Usage: %s [-h|--help] -H <hostname> [-p <port>] [-t <timeout>] [-T <retries>] [-v] [-i (KB|MB|GB)]\n"
32 . "[-1 | -2] [-c <community>]\n"
33 . "[-3] [-u <username>] [-a (md5|sha)] [-A <authpasswd>] [-x (des|aes)] [-X <privpasswd>]\n"
34 . " [-E <contextengineid>] [-n <contextname>]\n"
35 . "[-m <total-threshold>] [-M <total-threshold>] [-r <real-threshold>] [-R <real-threshold>]",
36 extra => "\nAll thresholds are in nagios standard format, see\n"
37 . "http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT\n"
38 . "for a description\n"
40 . "This check does currently not support setting the security engine id.\n",
41 url => "http://www.intra2net.com/en/developer/monitoring/",
42 license => "This nagios plugin is free software, and comes with ABSOLUTELY\n"
43 . "NO WARRANTY. It may be used, redistributed and/or modified under\n"
44 . "the terms of the GNU General Public Licence; either version 2\n"
45 . "of the License, or (at your option) any later version."
50 spec => "hostname|H=s",
51 help => "hostname or IP",
60 spec => "retries|T=i",
61 help => "SNMP retries on error, default: %s",
66 help => "unit for output and thresholds (KB|MB|GB), default: %s",
73 help => "use SNMP version 1"
77 help => "use SNMP version 2c"
80 spec => "community|c=s",
81 help => "SNMPv1/SNMPv2c community name, default: %s",
88 help => "use SNMP version 3"
92 spec => "username|u=s",
93 help => "SNMPv3 username"
96 spec => "authprotocol|a=s",
97 help => "SNMPv3 authentication protocol (md5|sha), default: %s",
101 spec => "authpassword|A=s",
102 help => "SNMPv3 authentication password"
105 spec => "privprotocol|x=s",
106 help => "SNMPv3 privacy protocol (des|aes), default: %s",
110 spec => "privpassword|X=s",
111 help => "SNMPv3 privacy password"
114 spec => "contextengineid|E=s",
115 help => "SNMPv3 context engine ID"
118 spec => "contextname|n=s",
119 help => "SNMPv3 context name"
124 spec => "totalavail-warning|m=s",
125 help => "Warning threshold for the total memory (real+swap) available, default: %s",
126 label => [ "FLOAT:FLOAT" ],
130 spec => "totalavail-critical|M=s",
131 help => "Critical threshold for the total memory (real+swap) available, default: %s",
132 label => [ "FLOAT:FLOAT" ],
136 spec => "realavail-warning|r=s",
137 help => "Warning threshold for the real memory available (free+buffer+cache), default: %s",
138 label => [ "FLOAT:FLOAT" ],
142 spec => "realavail-critical|R=s",
143 help => "Critical threshold for the real memory available (free+buffer+cache), default: %s",
144 label => [ "FLOAT:FLOAT" ],
151 ############ check & handle the unit parameter ############
154 if (uc($np->opts->get("unit")) eq "KB")
159 elsif (uc($np->opts->get("unit")) eq "MB")
164 elsif (uc($np->opts->get("unit")) eq "GB")
171 $np->nagios_die("illegal unit requested");
174 ############ sanity-check the snmp-version ############
175 my $snmpversion=undef;
177 if ($np->opts->get("snmpv1"))
181 if ($np->opts->get("snmpv2c"))
183 if (defined $snmpversion)
185 $np->nagios_die("you can only define one SNMP version");
192 if ($np->opts->get("snmpv3"))
194 if (defined $snmpversion)
196 $np->nagios_die("you can only define one SNMP version");
203 if (not defined $snmpversion)
205 # snmp default version
209 ############ create the SNMP session ############
210 my %snmpsessionparam = (
211 -hostname => $np->opts->get("hostname"),
212 -port => $np->opts->get("port"),
213 -version => $snmpversion,
214 -timeout => $np->opts->get("timeout"),
215 -retries => $np->opts->get("retries"),
217 my %snmprequestparam = ();
219 if ($snmpversion == 1 || $snmpversion == 2)
221 $snmpsessionparam{-community}=$np->opts->get("community");
225 $snmpsessionparam{-username}=$np->opts->get("username");
227 if (defined $np->opts->get("authpassword"))
229 $snmpsessionparam{-authprotocol}=$np->opts->get("authprotocol");
230 $snmpsessionparam{-authpassword}=$np->opts->get("authpassword");
233 if (defined $np->opts->get("privpassword"))
235 $snmpsessionparam{-privprotocol}=$np->opts->get("privprotocol");
236 $snmpsessionparam{-privpassword}=$np->opts->get("privpassword");
239 if (defined $np->opts->get("contextname"))
241 $snmprequestparam{-contextname}=$np->opts->get("contextname");
243 if (defined $np->opts->get("contextengineid"))
245 $snmprequestparam{-contextengineid}=$np->opts->get("contextengineid");
249 ($np->opts->get("verbose") > 1) && print Data::Dumper->Dump([\%snmpsessionparam], [qw(snmp_session_data)]);
251 my ($session,$snmperror)=Net::SNMP->session(%snmpsessionparam);
253 if (!defined $session)
255 $np->nagios_die("Error opening SNMP session: $snmperror");
258 ############ prepare & execute the snmp request ############
259 my $oid_memTotalSwap = "1.3.6.1.4.1.2021.4.3.0";
260 my $oid_memAvailSwap = "1.3.6.1.4.1.2021.4.4.0";
261 my $oid_memTotalReal = "1.3.6.1.4.1.2021.4.5.0";
262 my $oid_memAvailReal = "1.3.6.1.4.1.2021.4.6.0";
263 my $oid_memBuffer = "1.3.6.1.4.1.2021.4.14.0";
264 my $oid_memCached = "1.3.6.1.4.1.2021.4.15.0";
265 my $oid_ssSwapIn = "1.3.6.1.4.1.2021.11.3.0";
266 my $oid_ssSwapOut = "1.3.6.1.4.1.2021.11.4.0";
267 my $oid_intranator_swap_warning = "1.3.6.1.4.1.30475.1.1.3";
269 # we really need these oids to complete the check
270 my @essential_oidlist = ($oid_memTotalSwap, $oid_memAvailSwap, $oid_memTotalReal, $oid_memAvailReal,
271 $oid_memBuffer, $oid_memCached);
272 # all oids, including the additional ones
273 my @oidlist = (@essential_oidlist, $oid_ssSwapIn, $oid_ssSwapOut, $oid_intranator_swap_warning);
275 my %thisrequest=%snmprequestparam;
276 $thisrequest{-varbindlist}=\@oidlist;
278 ($np->opts->get("verbose") > 2) && print Data::Dumper->Dump([\%thisrequest], [qw(snmp_request_data)]);
280 my $result = $session->get_request(%thisrequest);
281 if (!defined $result)
283 $snmperror=$session->error;
285 $np->nagios_die("Error in SNMP request: $snmperror");
288 ($np->opts->get("verbose") > 0) && print Data::Dumper->Dump([$result], [qw(snmp_result)]);
292 ############ check if the essential oids are there ############
293 foreach my $oid (@essential_oidlist)
295 if (!defined $result->{$oid} || $result->{$oid} eq "noSuchObject")
297 $np->nagios_die("Essential OID $oid missing in result");
301 ############ interpret the results ############
302 # use only OIDs listed as essential here!
303 my $realmem=$result->{$oid_memTotalReal};
304 my $realavail=$result->{$oid_memAvailReal}+$result->{$oid_memBuffer}+$result->{$oid_memCached};
305 my $swap=$result->{$oid_memTotalSwap};
306 my $swapused=$swap-$result->{$oid_memAvailSwap};
307 my $totalavail=$realavail+$result->{$oid_memAvailSwap};
309 my $realpercent=sprintf("%.0f",($realavail/$realmem)*100);
310 my $totalpercent=sprintf("%.0f",($totalavail/($realmem+$swap))*100);
311 my $swappercent=sprintf("%.0f",($swapused/$swap)*100);
313 ############ convert the results to the desired unit ############
314 my @resultvar=(\$realmem, \$realavail, \$swap, \$swapused, \$totalavail);
315 foreach my $varref (@resultvar)
320 ############ check the thresholds ############
321 # do this BEFORE the rounding
324 push (@results, $np->check_threshold(
325 check => $totalavail,
326 warning => $np->opts->get("totalavail-warning"),
327 critical => $np->opts->get("totalavail-critical")
329 push (@results, $np->check_threshold(
331 warning => $np->opts->get("realavail-warning"),
332 critical => $np->opts->get("realavail-critical")
335 ############ rounding ############
336 # show decimals only if value less than limit
337 foreach my $varref (@resultvar)
341 $$varref=sprintf("%.2f",$$varref)
345 $$varref=sprintf("%.0f",$$varref)
349 ############ output the performance data ############
351 label => "total_avail",
352 value => $totalavail,
354 warning => $np->opts->get("totalavail-warning"),
355 critical => $np->opts->get("totalavail-critical"),
357 max => $swap+$realmem
360 label => "real_avail",
363 warning => $np->opts->get("realavail-warning"),
364 critical => $np->opts->get("realavail-critical"),
369 label => "swap_used",
376 ############ compose message ############
378 $np->max_state(@results),
379 "Real av: $realavail $unitstr ($realpercent%), Total av: $totalavail $unitstr ($totalpercent%), Swapped: $swapused $unitstr ($swappercent%)",