1 /*
2 * File: check_ucd_mem.c
3 * Copyright: (c) 2006 by Peter Gritsch
4 * Email: s4nag@no-where.at
5 *
6 * This file is part of SNMP4Nagios.
7 *
8 * SNMP4Nagios is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * SNMP4Nagios is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with SNMP4Nagios; if not, write to the
20 *
21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 * MA 02110-1301, USA
23 */
24
25 #if HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <errno.h>
30 #include "globals.h"
31 #include "nagiosif.h"
32 #if(WITH_RRD)
33 #include "rrdif.h"
34 #endif /* WITH_RRD */
35 #include "snmpif.h"
36 #include "syslogif.h"
37 #include "strutils.h"
38 #include "utilities.h"
39
40
41 /* data type for storing scan results */
42 /* Note: VMware ESX reports negative values for this. I've got to catch it. */
43 typedef struct
44 {
45 int v3; /* found memTotalSwap and is OK */
46 int v4; /* found memAvailSwap and is OK */
47 int v5; /* found memTotalReal and is OK */
48 int v6; /* found memAvailReal and is OK */
49 int v11; /* found memTotalFree and is OK */
50 int v13; /* found memShared and is OK */
51 int v14; /* found memBuffer and is OK */
52 int v15; /* found memCached and is OK */
53 } tScanRes;
54
55 /* data type for storing data */
56 typedef struct
57 {
58 int sTotal; /* total swap space */
59 int sAvail; /* available swap space */
60 int rTotal; /* total real/physical memory */
61 int rAvail; /* available real/physical memory */
62 int tAvail; /* total available (free) memory */
63 int shared; /* shared memory */
64 int buffer; /* buffered memory */
65 int cached; /* cache memory */
66 } tDataSet;
67
68
69 /* global input variables */
70 ulong warnS = 75; /* used virtual (=real+swap) memory */
71 char warnU = '%';
72 ulong critS = 85;
73 char critU = '%';
74
75 /*
76 * SNMP base OID
77 * UCD-SNMP-MIB::memTotalSwap.0 = 1.3.6.1.4.1.2021.4.3.0
78 * UCD-SNMP-MIB::memAvailSwap.0 = 1.3.6.1.4.1.2021.4.4.0
79 * UCD-SNMP-MIB::memTotalReal.0 = 1.3.6.1.4.1.2021.4.5.0
80 * UCD-SNMP-MIB::memAvailReal.0 = 1.3.6.1.4.1.2021.4.6.0
81 * UCD-SNMP-MIB::memTotalFree.0 = 1.3.6.1.4.1.2021.4.11.0
82 * UCD-SNMP-MIB::memShared.0 = 1.3.6.1.4.1.2021.4.13.0
83 * UCD-SNMP-MIB::memBuffer.0 = 1.3.6.1.4.1.2021.4.14.0
84 * UCD-SNMP-MIB::memCached.0 = 1.3.6.1.4.1.2021.4.15.0
85 */
86 oid baseOID[] = { 1, 3, 6, 1, 4, 1, 2021, 4 };
87 size_t baseOIDLen = 8;
88
89 /* scan results */
90 tScanRes* scanRes = NULL;
91 int scanResLen = 0;
92
93 /* results of the SNMP queries */
94 tDataSet v;
95
96
SetGlobals()97 void SetGlobals ()
98 {
99 /* progName is set by ReadArgs() */
100 srvName = "check_ucd_mem";
101 progVersion = "0.1";
102 helpIndexP = NULL;
103 helpThresP = "[-w WARN] [-c CRIT]";
104 helpPurpose = "Checks the memory usage of a u*ix computer.";
105 /* community is set by ReadArgs() */
106 /* commFile is set by ReadArgs() */
107 #if(WITH_RRD)
108 rrdStep = 1 * 60;
109 rrdHBeat = 3 * 60;
110 #endif /* WITH_RRD */
111 supportsPerfLog = TRUE;
112 hasIndexParam = FALSE;
113 hasAddInfParam = FALSE;
114 }
115
HelpSpecificParams()116 void HelpSpecificParams ()
117 {
118 printf (
119 "-w, --warning INTEGER[%%kMG]\n"
120 " Virtual (= swap + real) memory usage at which a warning is "
121 "generated.\n"
122 " Default is %lu%c.\n", warnS, warnU
123 );
124 printf (
125 "\n"
126 "-c, --critical INTEGER[%%kMG]\n"
127 " Virtual (= swap + real) memory usage at which a critical is "
128 "generated.\n"
129 " Default is %lu%c.\n", critS, critU
130 );
131 }
132
HelpExplain()133 void HelpExplain ()
134 {
135 printf (
136 "If the warning and critical parameters are given without unit, then the\n"
137 "unit Bytes is assumed. '%%', 'k', 'M' and 'G' are interpreted as\n"
138 "percent of the total space, Kilobytes (1024 Bytes), Megabytes\n"
139 "(1024*1024 Bytes) and Gigabytes (1024*1024*1024 Bytes) respectively.\n"
140 );
141 }
142
HelpPerformanceData()143 void HelpPerformanceData ()
144 {
145 printf (
146 "Native performance data is provided in the format (all in one line):\n"
147 "<sTotal>;<sAvail>;<rTotal>;<rAvail>;<tTotal>;<tAvail>;<shared>;\n"
148 "<buffer>;<cached>;\n"
149 "where\n"
150 " sTotal ... total swap space.\n"
151 " sAvail ... available swap space.\n"
152 " rTotal ... total real/physical memory.\n"
153 " rAvail ... available real/physical memory.\n"
154 " tTotal ... total memory.\n"
155 " tAvail ... total available memory.\n"
156 " shared ... shared memory.\n"
157 " buffer ... buffered memory.\n"
158 " cached ... cache memory.\n"
159 "\n"
160 );
161 printf (
162 "Nagios Plugins compatible performance data is provided in the format:\n"
163 "'swap space'=<sAvail>KB;;;0;<sTotal> "
164 "'real memory'=<rAvail>KB;;;0;<rTotal> "
165 "'available memory'=<tAvail>KB;<warn>;<crit>;0;<tTotal> "
166 "'shared memory'=<shared>KB "
167 "'buffered memory'=<buffer>KB "
168 "'cache memory'=<cached>KB\n"
169 "\n"
170 );
171 }
172
CheckSpaceUnit(char * aUnit)173 char CheckSpaceUnit ( char* aUnit )
174 {
175 char ret = '1';
176 if ( !strcmp ( aUnit, "" ) ) ret = '1';
177 else if ( !strcmp ( aUnit, "k" ) ) ret = 'k';
178 else if ( !strcmp ( aUnit, "M" ) ) ret = 'M';
179 else if ( !strcmp ( aUnit, "%" ) ) ret = '%';
180 else Usage ( "invalid space unit" );
181 return ( ret );
182 }
183
ChkOptSpecificParams(int argc,char ** argv,int * i)184 int ChkOptSpecificParams ( int argc, char** argv, int* i )
185 {
186 int ret = TRUE;
187
188 if ( !strcmp ( argv [(*i)], "-w" )
189 || !strcmp ( argv [(*i)], "--warning" ) )
190 {
191 (*i)++;
192 if ( (*i) < argc )
193 {
194 char *tail = argv [(*i)];
195 errno = 0;
196 warnS = strtoul ( argv [(*i)++], &tail, 0 );
197 if ( errno ) Usage ( "Invalid 'warn' parameter" );
198 warnU = CheckSpaceUnit ( tail );
199 } else Usage ( "Missing 'warn' parameter(s)" );
200 } else if ( !strcmp ( argv [(*i)], "-c" )
201 || !strcmp ( argv [(*i)], "--critical" ) )
202 {
203 (*i)++;
204 if ( (*i) < argc )
205 {
206 char *tail = argv [(*i)];
207 errno = 0;
208 critS = strtoul ( argv [(*i)++], &tail, 0 );
209 if ( errno ) Usage ( "Invalid 'crit' parameter" );
210 critU = CheckSpaceUnit ( tail );
211 } else Usage ( "Missing 'crit' parameter(s)" );
212 } else ret = FALSE;
213 return ( ret );
214 }
215
SnmpWalkHandleVariable(netsnmp_variable_list * aVar)216 void SnmpWalkHandleVariable ( netsnmp_variable_list* aVar )
217 {
218 if ( aVar->name_length == 10 )
219 {
220 if ( OidCmp ( aVar->name, baseOID, baseOIDLen ) == 0 )
221 {
222 if ( aVar->name [9] == 0 )
223 {
224 int typeOK = FALSE;
225 int valOK = FALSE;
226
227 switch ( aVar->name [8] )
228 {
229 case 3: /* memTotalSwap */
230 scanResLen = 1;
231 scanRes = realloc ( scanRes,
232 sizeof ( tScanRes ) * scanResLen );
233 if ( scanRes == NULL ) ErrorMalloc ();
234 typeOK = ( aVar->type == ASN_INTEGER );
235 valOK = ( *(aVar->val.integer) > 0 );
236 scanRes [0].v3 = ( typeOK && valOK );
237 scanRes [0].v4 = FALSE;
238 scanRes [0].v5 = FALSE;
239 scanRes [0].v6 = FALSE;
240 scanRes [0].v11 = FALSE;
241 scanRes [0].v13 = FALSE;
242 scanRes [0].v14 = FALSE;
243 scanRes [0].v15 = FALSE;
244 break;
245 case 4: /* memAvailSwap */
246 typeOK = ( aVar->type == ASN_INTEGER );
247 valOK = ( *(aVar->val.integer) > 0 );
248 scanRes [0].v4 = ( typeOK && valOK );
249 break;
250 case 5: /* memTotalReal */
251 typeOK = ( aVar->type == ASN_INTEGER );
252 valOK = ( *(aVar->val.integer) > 0 );
253 scanRes [0].v5 = ( typeOK && valOK );
254 break;
255 case 6: /* memAvailReal */
256 typeOK = ( aVar->type == ASN_INTEGER );
257 valOK = ( *(aVar->val.integer) > 0 );
258 scanRes [0].v6 = ( typeOK && valOK );
259 break;
260 case 11: /* memTotalFree */
261 typeOK = ( aVar->type == ASN_INTEGER );
262 valOK = ( *(aVar->val.integer) > 0 );
263 scanRes [0].v11 = ( typeOK && valOK );
264 break;
265 case 13: /* memShared */
266 typeOK = ( aVar->type == ASN_INTEGER );
267 valOK = ( *(aVar->val.integer) > 0 );
268 scanRes [0].v13 = ( typeOK && valOK );
269 break;
270 case 14: /* memBuffer */
271 typeOK = ( aVar->type == ASN_INTEGER );
272 valOK = ( *(aVar->val.integer) > 0 );
273 scanRes [0].v14 = ( typeOK && valOK );
274 break;
275 case 15: /* memCached */
276 typeOK = ( aVar->type == ASN_INTEGER );
277 valOK = ( *(aVar->val.integer) > 0 );
278 scanRes [0].v15 = ( typeOK && valOK );
279 break;
280 default:
281 /* don't care */
282 break;
283 }
284 }
285 else Log ( LOG_CRIT, "Unexpected index (!= 0) while scanning" );
286 } else Log ( LOG_CRIT, "Unexpected OID while scanning services" );
287 } else Log ( LOG_CRIT, "Wrong length while scanning services" );
288 }
289
ScanServices()290 int ScanServices ()
291 {
292 int i;
293 int retVal = STATE_UNKNOWN;
294
295 SnmpWalk ( baseOID, baseOIDLen );
296 for ( i = 0; i < scanResLen; i++ )
297 {
298 if ( scanRes [i].v3 && scanRes [i].v4 && scanRes [i].v5 &&
299 scanRes [i].v6 && scanRes [i].v11 && scanRes [i].v13 &&
300 scanRes [i].v14 && scanRes [i].v15 )
301 {
302 retVal = STATE_OK;
303 printf ( "OK\n" );
304 }
305 }
306 if ( retVal == STATE_UNKNOWN ) printf ( "FAILED\n" );
307 return retVal;
308 }
309
ReadVals()310 void ReadVals ()
311 {
312 struct snmp_session sess1;
313 struct snmp_session* sess2;
314 oid o_sTotal [10];
315 oid o_sAvail [10];
316 oid o_rTotal [10];
317 oid o_rAvail [10];
318 oid o_tAvail [10];
319 oid o_shared [10];
320 oid o_buffer [10];
321 oid o_cached [10];
322 size_t oidLen;
323
324 OidCpy ( o_sTotal, &oidLen, baseOID, &baseOIDLen );
325 OidCpy ( o_sAvail, &oidLen, baseOID, &baseOIDLen );
326 OidCpy ( o_rTotal, &oidLen, baseOID, &baseOIDLen );
327 OidCpy ( o_rAvail, &oidLen, baseOID, &baseOIDLen );
328 OidCpy ( o_tAvail, &oidLen, baseOID, &baseOIDLen );
329 OidCpy ( o_shared, &oidLen, baseOID, &baseOIDLen );
330 OidCpy ( o_buffer, &oidLen, baseOID, &baseOIDLen );
331 OidCpy ( o_cached, &oidLen, baseOID, &baseOIDLen );
332 o_sTotal [8] = 3; o_sTotal [9] = 0;
333 o_sAvail [8] = 4; o_sAvail [9] = 0;
334 o_rTotal [8] = 5; o_rTotal [9] = 0;
335 o_rAvail [8] = 6; o_rAvail [9] = 0;
336 o_tAvail [8] = 11; o_tAvail [9] = 0;
337 o_shared [8] = 13; o_shared [9] = 0;
338 o_buffer [8] = 14; o_buffer [9] = 0;
339 o_cached [8] = 15; o_cached [9] = 0;
340 oidLen = 10;
341 ConfigureSession1 ( &sess1 );
342 sess2 = snmp_open ( &sess1 );
343 if ( sess2 == NULL ) Error ( LOG_ERR, "Could not open session!" );
344 v.sTotal = ReadInteger ( sess2, o_sTotal, oidLen );
345 v.sAvail = ReadInteger ( sess2, o_sAvail, oidLen );
346 v.rTotal = ReadInteger ( sess2, o_rTotal, oidLen );
347 v.rAvail = ReadInteger ( sess2, o_rAvail, oidLen );
348 v.tAvail = ReadInteger ( sess2, o_tAvail, oidLen );
349 v.shared = ReadInteger ( sess2, o_shared, oidLen );
350 v.buffer = ReadInteger ( sess2, o_buffer, oidLen );
351 v.cached = ReadInteger ( sess2, o_cached, oidLen );
352 free ( sess1.peername );
353 free ( sess1.community );
354 snmp_close_sessions ();
355 }
356
357
358 #if(WITH_RRD)
CreateDataFile(const char * aRRDFPath)359 void CreateDataFile ( const char* aRRDFPath )
360 {
361 int i = 0;
362 char* params[1024]; /* Now that should be enough! */
363 params [i++] = StrDup ( "JUNK" );
364 params [i++] = StrDup ( aRRDFPath );
365 params [i++] = StrDup ( "-s" );
366 params [i++] = IntToStr ( rrdStep );
367 params [i++] = CreateDSStr ( "sTotal", GAUGE, rrdHBeat, "0", "U" );
368 params [i++] = CreateDSStr ( "sAvail", GAUGE, rrdHBeat, "0", "U" );
369 params [i++] = CreateDSStr ( "rTotal", GAUGE, rrdHBeat, "0", "U" );
370 params [i++] = CreateDSStr ( "rAvail", GAUGE, rrdHBeat, "0", "U" );
371 params [i++] = CreateDSStr ( "tAvail", GAUGE, rrdHBeat, "0", "U" );
372 params [i++] = CreateDSStr ( "shared", GAUGE, rrdHBeat, "0", "U" );
373 params [i++] = CreateDSStr ( "buffer", GAUGE, rrdHBeat, "0", "U" );
374 params [i++] = CreateDSStr ( "cached", GAUGE, rrdHBeat, "0", "U" );
375 params [i++] = RRA_MAX_25H_5M;
376 params [i++] = RRA_AVG_25H_5M;
377 params [i++] = RRA_MAX_8D_15M;
378 params [i++] = RRA_AVG_8D_15M;
379 params [i++] = RRA_MAX_32D_1H;
380 params [i++] = RRA_AVG_32D_1H;
381 params [i++] = RRA_MAX_367D_4H;
382 params [i++] = RRA_AVG_367D_4H;
383 RRDCreate ( i, params, aRRDFPath );
384 while ( i > 0 ) free ( params [--i] );
385 }
386
ParseData(const char * aData)387 void ParseData ( const char* aData )
388 {
389 int chk;
390 int junk;
391
392 chk = sscanf ( aData, "%i;%i;%i;%i;%i;%i;%i;%i;%i",
393 &(v.sTotal), &(v.sAvail), &(v.rTotal), &(v.rAvail),
394 &(junk),
395 &(v.tAvail), &(v.shared), &(v.buffer), &(v.cached) );
396 if ( chk != 8 )
397 {
398 char msg[1024];
399 snprintf ( msg, 1024,
400 "Could not parse performance data: %s.\n", aData );
401 Error ( LOG_ERR, msg );
402 }
403 }
404
WriteData(const char * aRRDFPath)405 void WriteData ( const char* aRRDFPath )
406 {
407 int i = 0;
408 char* params[1024]; /* Now that should be enough! */
409 char* ts = UIntToStr ( GetTimestamp () );
410 char* sTotal = IntToStr ( v.sTotal );
411 char* sAvail = IntToStr ( v.sAvail );
412 char* rTotal = IntToStr ( v.rTotal );
413 char* rAvail = IntToStr ( v.rAvail );
414 char* tAvail = IntToStr ( v.tAvail );
415 char* shared = IntToStr ( v.shared );
416 char* buffer = IntToStr ( v.buffer );
417 char* cached = IntToStr ( v.cached );
418
419 params [i++] = StrDup ( "JUNK" );
420 params [i++] = StrDup ( aRRDFPath );
421 params [i++] = StrDup ( "-t" );
422 params [i++] = StrDup (
423 "sTotal:sAvail:rTotal:rAvail:"
424 "tAvail:shared:buffer:cached" );
425 params [i++] = StrConcat ( 17, ts, ":",
426 sTotal, ":", sAvail, ":", rTotal, ":", rAvail, ":",
427 tAvail, ":", shared, ":", buffer, ":", cached );
428 RRDUpdate ( i, params, aRRDFPath );
429 while ( i > 0 ) free ( params [--i] );
430 free ( cached );
431 free ( buffer );
432 free ( shared );
433 free ( tAvail );
434 free ( rAvail );
435 free ( rTotal );
436 free ( sAvail );
437 free ( sTotal );
438 free ( ts );
439 }
440
PlotDataReal(tFN * aFN,int aTiming,int aNow)441 void PlotDataReal ( tFN* aFN, int aTiming, int aNow )
442 {
443 tPP* pp = PPInit ();
444 int i = 0;
445 char* title = NULL;
446 char* vLabel = "[%]";
447 char* params[1024]; /* Now that should be enough! */
448
449 FNSetPNGData ( aFN, "real", aTiming );
450 PPAddPlot ( pp, "used", "%", FALSE );
451 PPAddPlot ( pp, "shared", "%", TRUE );
452 PPAddPlot ( pp, "buffer", "%", TRUE );
453 PPAddPlot ( pp, "cached", "%", TRUE );
454 PPAddPlot ( pp, "tAvail", "%", TRUE );
455 title = StrConcat ( 2, hostName, " real memory" );
456 i = PlotStdParams ( params, aFN, title, vLabel,
457 aTiming, aNow - rrdHBeat, 1000, PLOT_SI_NONE, 0, 100, FALSE );
458 params [i++] = CreateDEF ( "sizeMR", aFN, "rTotal", MAX );
459 params [i++] = CreateDEF ( "sizeAR", aFN, "rTotal", AVG );
460 params [i++] = CreateDEF ( "sharMR", aFN, "shared", MAX );
461 params [i++] = CreateDEF ( "sharAR", aFN, "shared", AVG );
462 params [i++] = CreateDEF ( "buffMR", aFN, "buffer", MAX );
463 params [i++] = CreateDEF ( "buffAR", aFN, "buffer", AVG );
464 params [i++] = CreateDEF ( "cachMR", aFN, "cached", MAX );
465 params [i++] = CreateDEF ( "cachAR", aFN, "cached", AVG );
466 params [i++] = CreateDEF ( "freeMR", aFN, "rAvail", MAX );
467 params [i++] = CreateDEF ( "freeAR", aFN, "rAvail", AVG );
468 params [i++] = StrDup ( "CDEF:usedMR=sizeMR,sharMR,-,buffMR,-,cachMR,-,freeMR,-" );
469 params [i++] = StrDup ( "CDEF:usedAR=sizeAR,sharAR,-,buffAR,-,cachAR,-,freeAR,-" );
470 params [i++] = StrDup ( "CDEF:usedM=usedMR,sizeMR,/,100,*" );
471 params [i++] = StrDup ( "CDEF:usedA=usedAR,sizeAR,/,100,*" );
472 params [i++] = StrDup ( "CDEF:sharM=sharMR,sizeMR,/,100,*" );
473 params [i++] = StrDup ( "CDEF:sharA=sharAR,sizeAR,/,100,*" );
474 params [i++] = StrDup ( "CDEF:buffM=buffMR,sizeMR,/,100,*" );
475 params [i++] = StrDup ( "CDEF:buffA=buffAR,sizeAR,/,100,*" );
476 params [i++] = StrDup ( "CDEF:cachM=cachMR,sizeMR,/,100,*" );
477 params [i++] = StrDup ( "CDEF:cachA=cachAR,sizeAR,/,100,*" );
478 params [i++] = StrDup ( "CDEF:freeM=freeMR,sizeMR,/,100,*" );
479 params [i++] = StrDup ( "CDEF:freeA=freeAR,sizeAR,/,100,*" );
480 params [i++] = CreatePlot ( PLOT_AREA, "usedM", C_LOAD3_MAX, pp, 0, MAX, FALSE );
481 params [i++] = CreatePlot ( PLOT_STACK, "sharM", C_THRU_MAX, pp, 1, MAX, FALSE );
482 params [i++] = CreatePlot ( PLOT_STACK, "buffM", C_USAGE2_MAX, pp, 2, MAX, TRUE );
483 params [i++] = CreatePlot ( PLOT_STACK, "cachM", C_LOAD1_MAX, pp, 3, MAX, FALSE );
484 params [i++] = CreatePlot ( PLOT_STACK, "freeM", C_FREE_MAX, pp, 4, MAX, TRUE );
485 params [i++] = CreatePlot ( PLOT_LINE3, "usedA", C_LOAD3_AVG, pp, 0, AVG, FALSE );
486 params [i++] = CreatePlot ( PLOT_STACK, "sharA", C_THRU_AVG, pp, 1, AVG, FALSE );
487 params [i++] = CreatePlot ( PLOT_STACK, "buffA", C_USAGE2_AVG, pp, 2, AVG, TRUE );
488 params [i++] = CreatePlot ( PLOT_STACK, "cachA", C_LOAD1_AVG, pp, 3, AVG, FALSE );
489 params [i++] = CreatePlot ( PLOT_STACK, "freeA", C_FREE_AVG, pp, 4, AVG, TRUE );
490 i = PlotPrintParams ( i, params, pp, 0, "usedA", "usedA", "usedM", "usedM", "%5.1lf" );
491 i = PlotPrintParams ( i, params, pp, 1, "sharA", "sharA", "sharM", "sharM", "%5.1lf" );
492 i = PlotPrintParams ( i, params, pp, 2, "buffA", "buffA", "buffM", "buffM", "%5.1lf" );
493 i = PlotPrintParams ( i, params, pp, 3, "cachA", "cachA", "cachM", "cachM", "%5.1lf" );
494 i = PlotPrintParams ( i, params, pp, 4, "freeA", "freeA", "freeM", "freeM", "%5.1lf" );
495 RRDGraph ( i, params, aFN, pp );
496 while ( i > 0 ) free ( params [--i] );
497 free ( title );
498 PPDone ( pp );
499 FNUnsetPNGData ( aFN );
500 }
501
PlotDataSwap(tFN * aFN,int aTiming,int aNow)502 void PlotDataSwap ( tFN* aFN, int aTiming, int aNow )
503 {
504 tPP* pp = PPInit ();
505 int i = 0;
506 char* title = NULL;
507 char* vLabel = "[%]";
508 char* params[1024]; /* Now that should be enough! */
509
510 FNSetPNGData ( aFN, "swap", aTiming );
511 PPAddPlot ( pp, "used", "%", FALSE );
512 PPAddPlot ( pp, "free", "%", TRUE );
513 title = StrConcat ( 2, hostName, " swap memory" );
514 i = PlotStdParams ( params, aFN, title, vLabel,
515 aTiming, aNow - rrdHBeat, 1000, PLOT_SI_NONE, 0, 100, FALSE );
516 params [i++] = CreateDEF ( "sizeMR", aFN, "sTotal", MAX );
517 params [i++] = CreateDEF ( "sizeAR", aFN, "sTotal", AVG );
518 params [i++] = CreateDEF ( "freeMR", aFN, "sAvail", MAX );
519 params [i++] = CreateDEF ( "freeAR", aFN, "sAvail", AVG );
520 params [i++] = StrDup ( "CDEF:usedMR=sizeMR,freeMR,-" );
521 params [i++] = StrDup ( "CDEF:usedAR=sizeAR,freeAR,-" );
522 params [i++] = StrDup ( "CDEF:usedM=usedMR,sizeMR,/,100,*" );
523 params [i++] = StrDup ( "CDEF:usedA=usedAR,sizeAR,/,100,*" );
524 params [i++] = StrDup ( "CDEF:freeM=freeMR,sizeMR,/,100,*" );
525 params [i++] = StrDup ( "CDEF:freeA=freeAR,sizeAR,/,100,*" );
526 params [i++] = CreatePlot ( PLOT_AREA, "usedM", C_USAGE1_MAX, pp, 0, MAX, FALSE );
527 params [i++] = CreatePlot ( PLOT_STACK, "freeM", C_FREE_MAX, pp, 1, MAX, TRUE );
528 params [i++] = CreatePlot ( PLOT_LINE2, "usedA", C_USAGE1_AVG, pp, 0, AVG, FALSE );
529 params [i++] = CreatePlot ( PLOT_STACK, "freeA", C_FREE_AVG, pp, 1, AVG, TRUE );
530 i = PlotPrintParams ( i, params, pp, 0, "usedA", "usedA", "usedM", "usedM", "%5.1lf" );
531 i = PlotPrintParams ( i, params, pp, 1, "freeA", "freeA", "freeM", "freeM", "%5.1lf" );
532 RRDGraph ( i, params, aFN, pp );
533 while ( i > 0 ) free ( params [--i] );
534 free ( title );
535 PPDone ( pp );
536 FNUnsetPNGData ( aFN );
537 }
538
PlotPerfData()539 void PlotPerfData ()
540 {
541 int now = time ( NULL );
542 tFN* fn = FNInit ();
543
544 PlotDataReal ( fn, PLOT_6H_1M, now );
545 PlotDataSwap ( fn, PLOT_6H_1M, now );
546 PlotDataReal ( fn, PLOT_24H_5M, now );
547 PlotDataSwap ( fn, PLOT_24H_5M, now );
548 PlotDataReal ( fn, PLOT_7D_15M, now );
549 PlotDataSwap ( fn, PLOT_7D_15M, now );
550 PlotDataReal ( fn, PLOT_31D_60M, now );
551 PlotDataSwap ( fn, PLOT_31D_60M, now );
552 PlotDataReal ( fn, PLOT_366D_4H, now );
553 PlotDataSwap ( fn, PLOT_366D_4H, now );
554 FNDone ( fn );
555 }
556 #endif /* WITH_RRD */
557
LevelToKB(char * aWhat,int aLevel,char aUnit,int aSize)558 int LevelToKB ( char* aWhat, int aLevel, char aUnit, int aSize )
559 {
560 double retVal = 0.0;
561 double level = (double) aLevel;
562
563 switch ( aUnit )
564 {
565 case '1': retVal = level / 1024 ; break;
566 case 'k': retVal = level; break;
567 case 'M': retVal = level * 1024; break;
568 case 'G': retVal = level * 1024 * 1024; break;
569 case '%': retVal = ( level * aSize ) / 100; break;
570 default:
571 {
572 Error ( LOG_ERR, "An invalid level slipped through!" );
573 }
574 break;
575 }
576 return ( retVal );
577 }
578
CheckData()579 int CheckData ()
580 {
581 int retVal = STATE_OK;
582 int tTotal;
583 int tUsed;
584 int tWarn;
585 int tCrit;
586 int rUsed;
587 int sUsed;
588 double tUsedP;
589 double rUsedP;
590 double sUsedP;
591
592
593 ReadVals ();
594 /* calculate everything in Kibibytes */
595 tTotal = v.sTotal + v.rTotal;
596 tUsed = tTotal - v.tAvail;
597 tWarn = LevelToKB ( "warning level", warnS, warnU, tTotal );
598 tCrit = LevelToKB ( "critical level", critS, critU, tTotal );
599 rUsed = v.rTotal - v.rAvail;
600 sUsed = v.sTotal - v.sAvail;
601 tUsedP = ( ( (double) tUsed ) * 100.0 ) / (double) tTotal;
602 sUsedP = ( ( (double) sUsed ) * 100.0 ) / (double) v.sTotal;
603 rUsedP = ( ( (double) rUsed ) * 100.0 ) / (double) v.rTotal;
604 if ( tWarn < tUsed ) retVal = MAXIMUM ( retVal, STATE_WARNING );
605 if ( tCrit < tUsed ) retVal = MAXIMUM ( retVal, STATE_CRITICAL );
606 PrintExit ( retVal );
607 printf ( " - available/total real: %i/%iKB (%3.1f%%), swap: %i/%iKB (%3.1f%%)",
608 v.rAvail, v.rTotal, rUsedP, v.sAvail, v.sTotal, sUsedP );
609 if ( npPerfData )
610 {
611 printf ( "|'swap space'=%iKB;;;0;%i", v.sAvail, v.sTotal );
612 printf ( " 'real memory'=%iKB;;;0;%i", v.rAvail, v.rTotal );
613 printf ( " 'free memory'=%iKB;%i;%i;0;%i",
614 v.tAvail, tWarn, tCrit, tTotal );
615 printf ( " 'shared memory'=%iKB", v.shared );
616 printf ( " 'buffered memory'=%iKB", v.buffer );
617 printf ( " 'cache memory'=%iKB\n", v.cached );
618 }
619 else
620 {
621 printf ( "|%i;%i;%i;%i;%i;%i;%i;%i;%i\n",
622 v.sTotal, v.sAvail, v.rTotal, v.rAvail,
623 tTotal, v.tAvail, v.shared, v.buffer, v.cached );
624 }
625 return ( retVal );
626 }
627
main(int argc,char ** argv)628 int main ( int argc, char** argv )
629 {
630 int retVal = STATE_OK;
631
632 SetGlobals ();
633 ReadArgs ( argc, argv );
634 if ( scanServices ) retVal = ScanServices ();
635 else
636 {
637 if ( checkData ) retVal = CheckData ();
638 #if(WITH_RRD)
639 if ( logPerfData ) LogPerfData ();
640 if ( plotPerfData ) PlotPerfData ();
641 #endif /* WITH_RRD */
642 }
643 if ( hostName != NULL ) free ( hostName );
644 if ( hostAddr != NULL ) free ( hostAddr );
645 if ( progName != NULL ) free ( progName );
646 return ( retVal );
647 }
648