first working version of check_mem_ucd_snmp
[nagios-monitoring] / check_mem_ucd_snmp / check_mem_ucd_snmp
CommitLineData
e84dbce3
GE
1#!/usr/bin/perl -w
2#
3# check_mem_ucd_snmp: nagios-check testing the memory of a linux-system via SNMP
4#
5# see http://www.intra2net.com/en/developer/monitoring/
6# for current version, documentation, contact information etc.
7#
8# (C) 2009 by Gerd v. Egidy <gerd.von.egidy@intra2net.com>
9#
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.
14#
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.
19#
20
21use strict;
22use Nagios::Plugin;
23use Net::SNMP;
24use Data::Dumper;
25
26my $np = Nagios::Plugin->new(
27 plugin => "check_mem_ucd_snmp",
28 version => "0.1",
29 blurb => "nagios-check testing the memory of a linux-system via SNMP",
30 usage => "Usage: %s [-h|--help] -H <hostname> [-p <port>] [-t <timeout>] [-T <retries>] [-v] [-i (KB|MB|GB)]\n"
31 . "[-1 | -2] [-c <community>]\n"
32 . "[-3] [-u <username>] [-a (md5|sha)] [-A <authpasswd>] [-x (des|aes)] [-X <privpasswd>]\n"
33 . " [-E <contextengineid>] [-n <contextname>]\n"
34 . "[-t <total-threshold>] [-T <total-threshold>] [-r <real-threshold>] [-R <real-threshold>]",
35 extra => "\nAll thresholds are in nagios standard format, see\n"
36 . "http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT\n"
37 . "for a description\n"
38 . "\n"
39 . "This check does currently not support setting the security engine id.\n",
40 url => "http://www.intra2net.com/en/developer/monitoring/",
41 license => "This nagios plugin is free software, and comes with ABSOLUTELY\n"
42 . "NO WARRANTY. It may be used, redistributed and/or modified under\n"
43 . "the terms of the GNU General Public Licence; either version 2\n"
44 . "of the License, or (at your option) any later version."
45 );
46
47# basic options
48$np->add_arg(
49 spec => "hostname|H=s",
50 help => "hostname or IP",
51 required => 1
52 );
53$np->add_arg(
54 spec => "port|p=i",
55 help => "portnumber",
56 default => 161
57 );
58$np->add_arg(
59 spec => "retries|T=i",
60 help => "SNMP retries on error, default: %s",
61 default => 1
62 );
63$np->add_arg(
64 spec => "unit|i=s",
65 help => "unit for output and thresholds (KB|MB|GB), default: %s",
66 default => "MB"
67 );
68
69# snmp v1/v2c
70$np->add_arg(
71 spec => "snmpv1|1",
72 help => "use SNMP version 1"
73 );
74$np->add_arg(
75 spec => "snmpv2c|2",
76 help => "use SNMP version 2c"
77 );
78$np->add_arg(
79 spec => "community|c=s",
80 help => "SNMPv1/SNMPv2c community name, default: %s",
81 default => "public"
82 );
83
84# snmp v3
85$np->add_arg(
86 spec => "snmpv3|3",
87 help => "use SNMP version 3"
88 );
89
90$np->add_arg(
91 spec => "username|u=s",
92 help => "SNMPv3 username"
93 );
94$np->add_arg(
95 spec => "authprotocol|a=s",
96 help => "SNMPv3 authentication protocol (md5|sha), default: %s",
97 default => "md5"
98 );
99$np->add_arg(
100 spec => "authpassword|A=s",
101 help => "SNMPv3 authentication password"
102 );
103$np->add_arg(
104 spec => "privprotocol|x=s",
105 help => "SNMPv3 privacy protocol (des|aes), default: %s",
106 default => "des"
107 );
108$np->add_arg(
109 spec => "privpassword|X=s",
110 help => "SNMPv3 privacy password"
111 );
112$np->add_arg(
113 spec => "contextengineid|E=s",
114 help => "SNMPv3 context engine ID"
115 );
116$np->add_arg(
117 spec => "contextname|n=s",
118 help => "SNMPv3 context name"
119 );
120
121# thresholds
122$np->add_arg(
123 spec => "totalavail-warning|m=s",
124 help => "Warning threshold for the total memory (real+swap) available, default: %s",
125 label => [ "FLOAT:FLOAT" ],
126 default => "500:"
127 );
128$np->add_arg(
129 spec => "totalavail-critical|M=s",
130 help => "Critical threshold for the total memory (real+swap) available, default: %s",
131 label => [ "FLOAT:FLOAT" ],
132 default => "200:"
133 );
134$np->add_arg(
135 spec => "realavail-warning|r=s",
136 help => "Warning threshold for the real memory available (free+buffer+cache), default: %s",
137 label => [ "FLOAT:FLOAT" ],
138 default => "200:"
139 );
140$np->add_arg(
141 spec => "realavail-critical|R=s",
142 help => "Critical threshold for the real memory available (free+buffer+cache), default: %s",
143 label => [ "FLOAT:FLOAT" ],
144 default => "50:"
145 );
146
147# parse arguments
148$np->getopts;
149
150# care for the unit parameter
151my $unitstr;
152my $unitdiv;
153if (uc($np->opts->get("unit")) eq "KB")
154{
155 $unitstr="KB";
156 $unitdiv=1;
157}
158elsif (uc($np->opts->get("unit")) eq "MB")
159{
160 $unitstr="MB";
161 $unitdiv=1024;
162}
163elsif (uc($np->opts->get("unit")) eq "GB")
164{
165 $unitstr="GB";
166 $unitdiv=1024*1024;
167}
168else
169{
170 $np->nagios_die("illegal unit requested");
171}
172
173# sanity-check the snmp-version
174my $snmpversion=undef;
175
176if ($np->opts->get("snmpv1"))
177{
178 $snmpversion=1;
179}
180if ($np->opts->get("snmpv2c"))
181{
182 if (defined $snmpversion)
183 {
184 $np->nagios_die("you can only define one SNMP version");
185 }
186 else
187 {
188 $snmpversion=2;
189 }
190}
191if ($np->opts->get("snmpv3"))
192{
193 if (defined $snmpversion)
194 {
195 $np->nagios_die("you can only define one SNMP version");
196 }
197 else
198 {
199 $snmpversion=3;
200 }
201}
202if (not defined $snmpversion)
203{
204 # snmp default version
205 $snmpversion=2;
206}
207
208# create the SNMP session
209my %snmpsessionparam = (
210 -hostname => $np->opts->get("hostname"),
211 -port => $np->opts->get("port"),
212 -version => $snmpversion,
213 -timeout => $np->opts->get("timeout"),
214 -retries => $np->opts->get("retries"),
215 );
216my %snmprequestparam = ();
217
218if ($snmpversion == 1 || $snmpversion == 2)
219{
220 $snmpsessionparam{-community}=$np->opts->get("community");
221}
222else
223{
224 $snmpsessionparam{-username}=$np->opts->get("username");
225
226 if (defined $np->opts->get("authpassword"))
227 {
228 $snmpsessionparam{-authprotocol}=$np->opts->get("authprotocol");
229 $snmpsessionparam{-authpassword}=$np->opts->get("authpassword");
230 }
231
232 if (defined $np->opts->get("privpassword"))
233 {
234 $snmpsessionparam{-privprotocol}=$np->opts->get("privprotocol");
235 $snmpsessionparam{-privpassword}=$np->opts->get("privpassword");
236 }
237
238 if (defined $np->opts->get("contextname"))
239 {
240 $snmprequestparam{-contextname}=$np->opts->get("contextname");
241 }
242 if (defined $np->opts->get("contextengineid"))
243 {
244 $snmprequestparam{-contextengineid}=$np->opts->get("contextengineid");
245 }
246}
247
248($np->opts->get("verbose") > 1) && print Data::Dumper->Dump([\%snmpsessionparam], [qw(snmp_session_data)]);
249
250my ($session,$snmperror)=Net::SNMP->session(%snmpsessionparam);
251
252if (!defined $session)
253{
254 $np->nagios_die("Error opening SNMP session: $snmperror");
255}
256
257# prepare & execute the snmp request
258my $oid_memTotalSwap = "1.3.6.1.4.1.2021.4.3.0";
259my $oid_memAvailSwap = "1.3.6.1.4.1.2021.4.4.0";
260my $oid_memTotalReal = "1.3.6.1.4.1.2021.4.5.0";
261my $oid_memAvailReal = "1.3.6.1.4.1.2021.4.6.0";
262my $oid_memBuffer = "1.3.6.1.4.1.2021.4.14.0";
263my $oid_memCached = "1.3.6.1.4.1.2021.4.15.0";
264my $oid_ssSwapIn = "1.3.6.1.4.1.2021.11.3.0";
265my $oid_ssSwapOut = "1.3.6.1.4.1.2021.11.4.0";
266my $oid_intranator_swap_warning = "1.3.6.1.4.1.30475.1.1.3";
267
268# we really need these oids to complete the check
269my @essential_oidlist = ($oid_memTotalSwap, $oid_memAvailSwap, $oid_memTotalReal, $oid_memAvailReal,
270 $oid_memBuffer, $oid_memCached);
271# all oids, including the additional ones
272my @oidlist = (@essential_oidlist, $oid_ssSwapIn, $oid_ssSwapOut, $oid_intranator_swap_warning);
273
274my %thisrequest=%snmprequestparam;
275$thisrequest{-varbindlist}=\@oidlist;
276
277($np->opts->get("verbose") > 2) && print Data::Dumper->Dump([\%thisrequest], [qw(snmp_request_data)]);
278
279my $result = $session->get_request(%thisrequest);
280if (!defined $result)
281{
282 $snmperror=$session->error;
283 $session->close();
284 $np->nagios_die("Error in SNMP request: $snmperror");
285}
286
287($np->opts->get("verbose") > 0) && print Data::Dumper->Dump([$result], [qw(snmp_result)]);
288
289$session->close();
290
291# check if the essential oids are there
292foreach my $oid (@essential_oidlist)
293{
294 if (!defined $result->{$oid} || $result->{$oid} eq "noSuchObject")
295 {
296 $np->nagios_die("Essential OID $oid missing in result");
297 }
298}
299
300# interpret the results: use only OIDs listed as essential here!
301my $realmem=$result->{$oid_memTotalReal};
302my $realavail=$result->{$oid_memAvailReal}+$result->{$oid_memBuffer}+$result->{$oid_memCached};
303my $swap=$result->{$oid_memTotalSwap};
304my $swapused=$swap-$result->{$oid_memAvailSwap};
305my $totalavail=$realavail+$result->{$oid_memAvailSwap};
306
307my @resultvar=(\$realmem, \$realavail, \$swap, \$swapused, \$totalavail);
308foreach my $varref (@resultvar)
309{
310 $$varref/=$unitdiv;
311}
312
313# check the thresholds: do this BEFORE the rounding
314my @results = ();
315
316push (@results, $np->check_threshold(
317 check => $totalavail,
318 warning => $np->opts->get("totalavail-warning"),
319 critical => $np->opts->get("totalavail-critical")
320 ));
321push (@results, $np->check_threshold(
322 check => $realavail,
323 warning => $np->opts->get("realavail-warning"),
324 critical => $np->opts->get("realavail-critical")
325 ));
326
327# rounding: show decimals only if value less than limit
328foreach my $varref (@resultvar)
329{
330 if ($$varref < 20)
331 {
332 $$varref=sprintf("%.2f",$$varref)
333 }
334 else
335 {
336 $$varref=sprintf("%.0f",$$varref)
337 }
338}
339
340# output the performance data
341$np->add_perfdata(
342 label => "total_avail",
343 value => $totalavail,
344 uom => $unitstr,
345 warning => $np->opts->get("totalavail-warning"),
346 critical => $np->opts->get("totalavail-critical"),
347 min => 0,
348 max => $swap+$realmem
349 );
350$np->add_perfdata(
351 label => "real_avail",
352 value => $realavail,
353 uom => $unitstr,
354 warning => $np->opts->get("realavail-warning"),
355 critical => $np->opts->get("realavail-critical"),
356 min => 0,
357 max => $realmem
358 );
359$np->add_perfdata(
360 label => "swap_used",
361 value => $swapused,
362 uom => $unitstr,
363 min => 0,
364 max => $swap
365 );
366
367# compose message
368$np->nagios_exit(
369 $np->max_state(@results),
370 "Real av: $realavail $unitstr, Total av: $totalavail $unitstr, Swapped: $swapused $unitstr",
371 );