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 | ||
26 | my $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 | |
151 | my $unitstr; | |
152 | my $unitdiv; | |
153 | if (uc($np->opts->get("unit")) eq "KB") | |
154 | { | |
155 | $unitstr="KB"; | |
156 | $unitdiv=1; | |
157 | } | |
158 | elsif (uc($np->opts->get("unit")) eq "MB") | |
159 | { | |
160 | $unitstr="MB"; | |
161 | $unitdiv=1024; | |
162 | } | |
163 | elsif (uc($np->opts->get("unit")) eq "GB") | |
164 | { | |
165 | $unitstr="GB"; | |
166 | $unitdiv=1024*1024; | |
167 | } | |
168 | else | |
169 | { | |
170 | $np->nagios_die("illegal unit requested"); | |
171 | } | |
172 | ||
173 | # sanity-check the snmp-version | |
174 | my $snmpversion=undef; | |
175 | ||
176 | if ($np->opts->get("snmpv1")) | |
177 | { | |
178 | $snmpversion=1; | |
179 | } | |
180 | if ($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 | } | |
191 | if ($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 | } | |
202 | if (not defined $snmpversion) | |
203 | { | |
204 | # snmp default version | |
205 | $snmpversion=2; | |
206 | } | |
207 | ||
208 | # create the SNMP session | |
209 | my %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 | ); | |
216 | my %snmprequestparam = (); | |
217 | ||
218 | if ($snmpversion == 1 || $snmpversion == 2) | |
219 | { | |
220 | $snmpsessionparam{-community}=$np->opts->get("community"); | |
221 | } | |
222 | else | |
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 | ||
250 | my ($session,$snmperror)=Net::SNMP->session(%snmpsessionparam); | |
251 | ||
252 | if (!defined $session) | |
253 | { | |
254 | $np->nagios_die("Error opening SNMP session: $snmperror"); | |
255 | } | |
256 | ||
257 | # prepare & execute the snmp request | |
258 | my $oid_memTotalSwap = "1.3.6.1.4.1.2021.4.3.0"; | |
259 | my $oid_memAvailSwap = "1.3.6.1.4.1.2021.4.4.0"; | |
260 | my $oid_memTotalReal = "1.3.6.1.4.1.2021.4.5.0"; | |
261 | my $oid_memAvailReal = "1.3.6.1.4.1.2021.4.6.0"; | |
262 | my $oid_memBuffer = "1.3.6.1.4.1.2021.4.14.0"; | |
263 | my $oid_memCached = "1.3.6.1.4.1.2021.4.15.0"; | |
264 | my $oid_ssSwapIn = "1.3.6.1.4.1.2021.11.3.0"; | |
265 | my $oid_ssSwapOut = "1.3.6.1.4.1.2021.11.4.0"; | |
266 | my $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 | |
269 | my @essential_oidlist = ($oid_memTotalSwap, $oid_memAvailSwap, $oid_memTotalReal, $oid_memAvailReal, | |
270 | $oid_memBuffer, $oid_memCached); | |
271 | # all oids, including the additional ones | |
272 | my @oidlist = (@essential_oidlist, $oid_ssSwapIn, $oid_ssSwapOut, $oid_intranator_swap_warning); | |
273 | ||
274 | my %thisrequest=%snmprequestparam; | |
275 | $thisrequest{-varbindlist}=\@oidlist; | |
276 | ||
277 | ($np->opts->get("verbose") > 2) && print Data::Dumper->Dump([\%thisrequest], [qw(snmp_request_data)]); | |
278 | ||
279 | my $result = $session->get_request(%thisrequest); | |
280 | if (!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 | |
292 | foreach 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! | |
301 | my $realmem=$result->{$oid_memTotalReal}; | |
302 | my $realavail=$result->{$oid_memAvailReal}+$result->{$oid_memBuffer}+$result->{$oid_memCached}; | |
303 | my $swap=$result->{$oid_memTotalSwap}; | |
304 | my $swapused=$swap-$result->{$oid_memAvailSwap}; | |
305 | my $totalavail=$realavail+$result->{$oid_memAvailSwap}; | |
306 | ||
307 | my @resultvar=(\$realmem, \$realavail, \$swap, \$swapused, \$totalavail); | |
308 | foreach my $varref (@resultvar) | |
309 | { | |
310 | $$varref/=$unitdiv; | |
311 | } | |
312 | ||
313 | # check the thresholds: do this BEFORE the rounding | |
314 | my @results = (); | |
315 | ||
316 | push (@results, $np->check_threshold( | |
317 | check => $totalavail, | |
318 | warning => $np->opts->get("totalavail-warning"), | |
319 | critical => $np->opts->get("totalavail-critical") | |
320 | )); | |
321 | push (@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 | |
328 | foreach 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 | ); |