Commit | Line | Data |
---|---|---|
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 | ||
21 | use strict; | |
22 | use Nagios::Plugin; | |
23 | use Net::SNMP; | |
24 | use Data::Dumper; | |
25 | ||
d6d37c3f | 26 | ############ basic plugin data & argument handling ############ |
e84dbce3 GE |
27 | my $np = Nagios::Plugin->new( |
28 | plugin => "check_mem_ucd_snmp", | |
29 | version => "0.1", | |
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 | . "[-t <total-threshold>] [-T <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" | |
39 | . "\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." | |
46 | ); | |
47 | ||
48 | # basic options | |
49 | $np->add_arg( | |
50 | spec => "hostname|H=s", | |
51 | help => "hostname or IP", | |
52 | required => 1 | |
53 | ); | |
54 | $np->add_arg( | |
55 | spec => "port|p=i", | |
56 | help => "portnumber", | |
57 | default => 161 | |
58 | ); | |
59 | $np->add_arg( | |
60 | spec => "retries|T=i", | |
61 | help => "SNMP retries on error, default: %s", | |
62 | default => 1 | |
63 | ); | |
64 | $np->add_arg( | |
65 | spec => "unit|i=s", | |
66 | help => "unit for output and thresholds (KB|MB|GB), default: %s", | |
67 | default => "MB" | |
68 | ); | |
69 | ||
70 | # snmp v1/v2c | |
71 | $np->add_arg( | |
72 | spec => "snmpv1|1", | |
73 | help => "use SNMP version 1" | |
74 | ); | |
75 | $np->add_arg( | |
76 | spec => "snmpv2c|2", | |
77 | help => "use SNMP version 2c" | |
78 | ); | |
79 | $np->add_arg( | |
80 | spec => "community|c=s", | |
81 | help => "SNMPv1/SNMPv2c community name, default: %s", | |
82 | default => "public" | |
83 | ); | |
84 | ||
85 | # snmp v3 | |
86 | $np->add_arg( | |
87 | spec => "snmpv3|3", | |
88 | help => "use SNMP version 3" | |
89 | ); | |
90 | ||
91 | $np->add_arg( | |
92 | spec => "username|u=s", | |
93 | help => "SNMPv3 username" | |
94 | ); | |
95 | $np->add_arg( | |
96 | spec => "authprotocol|a=s", | |
97 | help => "SNMPv3 authentication protocol (md5|sha), default: %s", | |
98 | default => "md5" | |
99 | ); | |
100 | $np->add_arg( | |
101 | spec => "authpassword|A=s", | |
102 | help => "SNMPv3 authentication password" | |
103 | ); | |
104 | $np->add_arg( | |
105 | spec => "privprotocol|x=s", | |
106 | help => "SNMPv3 privacy protocol (des|aes), default: %s", | |
107 | default => "des" | |
108 | ); | |
109 | $np->add_arg( | |
110 | spec => "privpassword|X=s", | |
111 | help => "SNMPv3 privacy password" | |
112 | ); | |
113 | $np->add_arg( | |
114 | spec => "contextengineid|E=s", | |
115 | help => "SNMPv3 context engine ID" | |
116 | ); | |
117 | $np->add_arg( | |
118 | spec => "contextname|n=s", | |
119 | help => "SNMPv3 context name" | |
120 | ); | |
121 | ||
122 | # thresholds | |
123 | $np->add_arg( | |
124 | spec => "totalavail-warning|m=s", | |
125 | help => "Warning threshold for the total memory (real+swap) available, default: %s", | |
126 | label => [ "FLOAT:FLOAT" ], | |
127 | default => "500:" | |
128 | ); | |
129 | $np->add_arg( | |
130 | spec => "totalavail-critical|M=s", | |
131 | help => "Critical threshold for the total memory (real+swap) available, default: %s", | |
132 | label => [ "FLOAT:FLOAT" ], | |
133 | default => "200:" | |
134 | ); | |
135 | $np->add_arg( | |
136 | spec => "realavail-warning|r=s", | |
137 | help => "Warning threshold for the real memory available (free+buffer+cache), default: %s", | |
138 | label => [ "FLOAT:FLOAT" ], | |
139 | default => "200:" | |
140 | ); | |
141 | $np->add_arg( | |
142 | spec => "realavail-critical|R=s", | |
143 | help => "Critical threshold for the real memory available (free+buffer+cache), default: %s", | |
144 | label => [ "FLOAT:FLOAT" ], | |
145 | default => "50:" | |
146 | ); | |
147 | ||
148 | # parse arguments | |
149 | $np->getopts; | |
150 | ||
d6d37c3f | 151 | ############ check & handle the unit parameter ############ |
e84dbce3 GE |
152 | my $unitstr; |
153 | my $unitdiv; | |
154 | if (uc($np->opts->get("unit")) eq "KB") | |
155 | { | |
156 | $unitstr="KB"; | |
157 | $unitdiv=1; | |
158 | } | |
159 | elsif (uc($np->opts->get("unit")) eq "MB") | |
160 | { | |
161 | $unitstr="MB"; | |
162 | $unitdiv=1024; | |
163 | } | |
164 | elsif (uc($np->opts->get("unit")) eq "GB") | |
165 | { | |
166 | $unitstr="GB"; | |
167 | $unitdiv=1024*1024; | |
168 | } | |
169 | else | |
170 | { | |
171 | $np->nagios_die("illegal unit requested"); | |
172 | } | |
173 | ||
d6d37c3f | 174 | ############ sanity-check the snmp-version ############ |
e84dbce3 GE |
175 | my $snmpversion=undef; |
176 | ||
177 | if ($np->opts->get("snmpv1")) | |
178 | { | |
179 | $snmpversion=1; | |
180 | } | |
181 | if ($np->opts->get("snmpv2c")) | |
182 | { | |
183 | if (defined $snmpversion) | |
184 | { | |
185 | $np->nagios_die("you can only define one SNMP version"); | |
186 | } | |
187 | else | |
188 | { | |
189 | $snmpversion=2; | |
190 | } | |
191 | } | |
192 | if ($np->opts->get("snmpv3")) | |
193 | { | |
194 | if (defined $snmpversion) | |
195 | { | |
196 | $np->nagios_die("you can only define one SNMP version"); | |
197 | } | |
198 | else | |
199 | { | |
200 | $snmpversion=3; | |
201 | } | |
202 | } | |
203 | if (not defined $snmpversion) | |
204 | { | |
205 | # snmp default version | |
206 | $snmpversion=2; | |
207 | } | |
208 | ||
d6d37c3f | 209 | ############ create the SNMP session ############ |
e84dbce3 GE |
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"), | |
216 | ); | |
217 | my %snmprequestparam = (); | |
218 | ||
219 | if ($snmpversion == 1 || $snmpversion == 2) | |
220 | { | |
221 | $snmpsessionparam{-community}=$np->opts->get("community"); | |
222 | } | |
223 | else | |
224 | { | |
225 | $snmpsessionparam{-username}=$np->opts->get("username"); | |
226 | ||
227 | if (defined $np->opts->get("authpassword")) | |
228 | { | |
229 | $snmpsessionparam{-authprotocol}=$np->opts->get("authprotocol"); | |
230 | $snmpsessionparam{-authpassword}=$np->opts->get("authpassword"); | |
231 | } | |
232 | ||
233 | if (defined $np->opts->get("privpassword")) | |
234 | { | |
235 | $snmpsessionparam{-privprotocol}=$np->opts->get("privprotocol"); | |
236 | $snmpsessionparam{-privpassword}=$np->opts->get("privpassword"); | |
237 | } | |
238 | ||
239 | if (defined $np->opts->get("contextname")) | |
240 | { | |
241 | $snmprequestparam{-contextname}=$np->opts->get("contextname"); | |
242 | } | |
243 | if (defined $np->opts->get("contextengineid")) | |
244 | { | |
245 | $snmprequestparam{-contextengineid}=$np->opts->get("contextengineid"); | |
246 | } | |
247 | } | |
248 | ||
249 | ($np->opts->get("verbose") > 1) && print Data::Dumper->Dump([\%snmpsessionparam], [qw(snmp_session_data)]); | |
250 | ||
251 | my ($session,$snmperror)=Net::SNMP->session(%snmpsessionparam); | |
252 | ||
253 | if (!defined $session) | |
254 | { | |
255 | $np->nagios_die("Error opening SNMP session: $snmperror"); | |
256 | } | |
257 | ||
d6d37c3f | 258 | ############ prepare & execute the snmp request ############ |
e84dbce3 GE |
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"; | |
268 | ||
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); | |
274 | ||
275 | my %thisrequest=%snmprequestparam; | |
276 | $thisrequest{-varbindlist}=\@oidlist; | |
277 | ||
278 | ($np->opts->get("verbose") > 2) && print Data::Dumper->Dump([\%thisrequest], [qw(snmp_request_data)]); | |
279 | ||
280 | my $result = $session->get_request(%thisrequest); | |
281 | if (!defined $result) | |
282 | { | |
283 | $snmperror=$session->error; | |
284 | $session->close(); | |
285 | $np->nagios_die("Error in SNMP request: $snmperror"); | |
286 | } | |
287 | ||
288 | ($np->opts->get("verbose") > 0) && print Data::Dumper->Dump([$result], [qw(snmp_result)]); | |
289 | ||
290 | $session->close(); | |
291 | ||
d6d37c3f | 292 | ############ check if the essential oids are there ############ |
e84dbce3 GE |
293 | foreach my $oid (@essential_oidlist) |
294 | { | |
295 | if (!defined $result->{$oid} || $result->{$oid} eq "noSuchObject") | |
296 | { | |
297 | $np->nagios_die("Essential OID $oid missing in result"); | |
298 | } | |
299 | } | |
300 | ||
d6d37c3f GE |
301 | ############ interpret the results ############ |
302 | # use only OIDs listed as essential here! | |
e84dbce3 GE |
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}; | |
308 | ||
d6d37c3f | 309 | ############ convert the results to the desired unit ############ |
e84dbce3 GE |
310 | my @resultvar=(\$realmem, \$realavail, \$swap, \$swapused, \$totalavail); |
311 | foreach my $varref (@resultvar) | |
312 | { | |
313 | $$varref/=$unitdiv; | |
314 | } | |
315 | ||
d6d37c3f GE |
316 | ############ check the thresholds ############ |
317 | # do this BEFORE the rounding | |
e84dbce3 GE |
318 | my @results = (); |
319 | ||
320 | push (@results, $np->check_threshold( | |
321 | check => $totalavail, | |
322 | warning => $np->opts->get("totalavail-warning"), | |
323 | critical => $np->opts->get("totalavail-critical") | |
324 | )); | |
325 | push (@results, $np->check_threshold( | |
326 | check => $realavail, | |
327 | warning => $np->opts->get("realavail-warning"), | |
328 | critical => $np->opts->get("realavail-critical") | |
329 | )); | |
330 | ||
d6d37c3f GE |
331 | ############ rounding ############ |
332 | # show decimals only if value less than limit | |
e84dbce3 GE |
333 | foreach my $varref (@resultvar) |
334 | { | |
335 | if ($$varref < 20) | |
336 | { | |
337 | $$varref=sprintf("%.2f",$$varref) | |
338 | } | |
339 | else | |
340 | { | |
341 | $$varref=sprintf("%.0f",$$varref) | |
342 | } | |
343 | } | |
344 | ||
d6d37c3f | 345 | ############ output the performance data ############ |
e84dbce3 GE |
346 | $np->add_perfdata( |
347 | label => "total_avail", | |
348 | value => $totalavail, | |
349 | uom => $unitstr, | |
350 | warning => $np->opts->get("totalavail-warning"), | |
351 | critical => $np->opts->get("totalavail-critical"), | |
352 | min => 0, | |
353 | max => $swap+$realmem | |
354 | ); | |
355 | $np->add_perfdata( | |
356 | label => "real_avail", | |
357 | value => $realavail, | |
358 | uom => $unitstr, | |
359 | warning => $np->opts->get("realavail-warning"), | |
360 | critical => $np->opts->get("realavail-critical"), | |
361 | min => 0, | |
362 | max => $realmem | |
363 | ); | |
364 | $np->add_perfdata( | |
365 | label => "swap_used", | |
366 | value => $swapused, | |
367 | uom => $unitstr, | |
368 | min => 0, | |
369 | max => $swap | |
370 | ); | |
371 | ||
d6d37c3f | 372 | ############ compose message ############ |
e84dbce3 GE |
373 | $np->nagios_exit( |
374 | $np->max_state(@results), | |
375 | "Real av: $realavail $unitstr, Total av: $totalavail $unitstr, Swapped: $swapused $unitstr", | |
376 | ); |