1 /*----------------------------------------------------------------------------*/
2 /* Xymon message daemon. */
3 /* */
4 /* Copyright (C) 2004-2011 Henrik Storner <henrik@hswn.dk> */
5 /* */
6 /* This program is released under the GNU General Public License (GPL), */
7 /* version 2. See the file "COPYING" for details. */
8 /* */
9 /*----------------------------------------------------------------------------*/
10
11 static char rcsid[] = "$Id: do_rrd.c 7608 2015-03-21 15:00:40Z jccleaver $";
12
13 #include <sys/types.h>
14 #include <sys/time.h>
15 #include <sys/stat.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <limits.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <utime.h>
24
25 #include <rrd.h>
26 #include <pcre.h>
27
28 #include "libxymon.h"
29
30 #include "xymond_rrd.h"
31 #include "do_rrd.h"
32 #include "client_config.h"
33
34 #ifndef NAME_MAX
35 #define NAME_MAX 255 /* Solaris doesn't define NAME_MAX, but ufs limit is 255 */
36 #endif
37
38 extern int seq; /* from xymond_rrd.c */
39
40 char *rrddir = NULL;
41 int use_rrd_cache = 1; /* Use the cache by default */
42 int no_rrd = 0; /* Write to rrd by default */
43
44 static int processorfd = 0;
45 static FILE *processorstream = NULL;
46
47 static char *exthandler = NULL;
48 static char **extids = NULL;
49
50 static char rrdvalues[MAX_LINE_LEN];
51
52 static char *senderip = NULL;
53 static char rrdfn[PATH_MAX]; /* Base filename without directories, from setupfn() */
54 static char filedir[PATH_MAX]; /* Full path filename */
55 static char *fnparams[4] = { NULL, }; /* Saved parameters passed to setupfn() */
56
57 /* How often do we feed data into the RRD file */
58 #define DEFAULT_RRD_INTERVAL 300
59 static int rrdinterval = DEFAULT_RRD_INTERVAL;
60
61 #define CACHESZ 12 /* # of updates that can be cached - updates are usually 5 minutes apart */
62 static int updcache_keyofs = -1;
63 static void * updcache;
64 typedef struct updcacheitem_t {
65 char *key;
66 rrdtpldata_t *tpl;
67 int valcount;
68 char *vals[CACHESZ];
69 int updseq[CACHESZ];
70 time_t updtime[CACHESZ];
71 } updcacheitem_t;
72
73 static void * flushtree;
74 static int have_flushtree = 0;
75 typedef struct flushtree_t {
76 char *hostname;
77 time_t flushtime;
78 } flushtree_t;
79
80
setup_exthandler(char * handlerpath,char * ids)81 void setup_exthandler(char *handlerpath, char *ids)
82 {
83 char *p;
84 int idcount = 0;
85
86 MEMDEFINE(rrdvalues);
87
88 exthandler = strdup(handlerpath);
89 idcount=1; p = ids; while ((p = strchr(p, ',')) != NULL) { p++; idcount++; }
90 extids = (char **)malloc((idcount+1)*(sizeof(char *)));
91 idcount = 0;
92 p = strtok(ids, ",");
93 while (p) {
94 extids[idcount++] = strdup(p);
95 p = strtok(NULL, ",");
96 }
97 extids[idcount] = NULL;
98
99 MEMUNDEFINE(rrdvalues);
100 }
101
setup_extprocessor(char * cmd)102 void setup_extprocessor(char *cmd)
103 {
104
105 int n;
106 int pfd[2];
107 pid_t childpid;
108
109 if (!cmd) return;
110
111 processorfd = 0;
112
113 n = pipe(pfd);
114 if (n == -1) {
115 errprintf("Could not get a pipe: %s\n", strerror(errno));
116 }
117 else {
118 childpid = fork();
119 if (childpid == -1) {
120 errprintf("Could not fork channel handler: %s\n", strerror(errno));
121 }
122 else if (childpid == 0) {
123 /* The channel handler child */
124 char *argv[2];
125
126 argv[0] = strdup(cmd);
127 argv[1] = NULL;
128
129 n = dup2(pfd[0], STDIN_FILENO);
130 close(pfd[0]); close(pfd[1]);
131 n = execvp(cmd, argv);
132
133 /* We should never go here */
134 errprintf("exec() failed for child command %s: %s\n", cmd, strerror(errno));
135 exit(1);
136 }
137 else {
138 /* Parent process continues */
139 close(pfd[0]);
140 processorfd = pfd[1];
141 processorstream = fdopen(processorfd, "w");
142 errprintf("External processor '%s' started\n", cmd);
143 }
144 }
145 }
146
shutdown_extprocessor(void)147 void shutdown_extprocessor(void)
148 {
149 if (!processorfd) return;
150
151 close(processorfd);
152 processorfd = 0;
153 processorstream = NULL;
154
155 errprintf("External processor stopped\n");
156 }
157
158
setupfn(char * format,char * param)159 static void setupfn(char *format, char *param)
160 {
161 char *p;
162
163 memset(fnparams, 0, sizeof(fnparams));
164 fnparams[0] = param;
165
166 snprintf(rrdfn, sizeof(rrdfn)-1, format, param);
167 rrdfn[sizeof(rrdfn)-1] = '\0';
168 while ((p = strchr(rrdfn, ' ')) != NULL) *p = '_';
169 }
170
setupfn2(char * format,char * param1,char * param2)171 static void setupfn2(char *format, char *param1, char *param2)
172 {
173 char *p;
174
175 while ((p = strchr(param2, '/')) != NULL) *p = ',';
176
177 memset(fnparams, 0, sizeof(fnparams));
178 fnparams[0] = param1;
179 fnparams[1] = param2;
180
181 snprintf(rrdfn, sizeof(rrdfn)-1, format, param1, param2);
182 rrdfn[sizeof(rrdfn)-1] = '\0';
183 while ((p = strchr(rrdfn, ' ')) != NULL) *p = '_';
184 }
185
setupfn3(char * format,char * param1,char * param2,char * param3)186 static void setupfn3(char *format, char *param1, char *param2, char *param3)
187 {
188 char *p;
189
190 memset(fnparams, 0, sizeof(fnparams));
191 fnparams[0] = param1;
192 fnparams[1] = param2;
193 fnparams[2] = param3;
194
195 snprintf(rrdfn, sizeof(rrdfn)-1, format, param1, param2, param3);
196 rrdfn[sizeof(rrdfn)-1] = '\0';
197 while ((p = strchr(rrdfn, ' ')) != NULL) *p = '_';
198
199 if (strlen(rrdfn) >= (NAME_MAX - 50)) {
200 /*
201 * Filename is too long. Limit filename length
202 * by replacing the last part of the filename
203 * with an MD5 hash.
204 */
205 char *hash = md5hash(rrdfn+(NAME_MAX-50));
206
207 sprintf(rrdfn+(NAME_MAX-50), "_%s.rrd", hash);
208 }
209 }
210
setupinterval(int intvl)211 static void setupinterval(int intvl)
212 {
213 rrdinterval = (intvl ? intvl : DEFAULT_RRD_INTERVAL);
214 }
215
flush_cached_updates(updcacheitem_t * cacheitem,char * newdata)216 static int flush_cached_updates(updcacheitem_t *cacheitem, char *newdata)
217 {
218 /* Flush any updates we've cached */
219 char *updparams[5+CACHESZ+1] = { "rrdupdate", filedir, "-t", NULL, NULL, NULL, };
220 int i, pcount, result;
221
222 dbgprintf("Flushing '%s' with %d updates pending, template '%s'\n",
223 cacheitem->key, (newdata ? 1 : 0) + cacheitem->valcount, cacheitem->tpl->template);
224
225 /* ISO C90: parameters cannot be used as initializers */
226 updparams[3] = cacheitem->tpl->template;
227
228 /* Setup the parameter list with all of the cached and new readings */
229 for (i=0; (i < cacheitem->valcount); i++) updparams[4+i] = cacheitem->vals[i];
230
231 if (newdata) {
232 updparams[4+cacheitem->valcount] = newdata;
233 updparams[4+cacheitem->valcount+1] = NULL;
234 }
235 else {
236 /* No new data - happens when flushing the cache */
237 updparams[4+cacheitem->valcount] = NULL;
238 }
239
240 for (pcount = 0; (updparams[pcount]); pcount++);
241 optind = opterr = 0; rrd_clear_error();
242 result = rrd_update(pcount, updparams);
243
244 #if defined(LINUX) && defined(RRDTOOL12)
245 /*
246 * RRDtool 1.2+ uses mmap'ed I/O, but the Linux kernel does not update timestamps when
247 * doing file I/O on mmap'ed files. This breaks our check for stale/nostale RRD's.
248 * So do an explicit timestamp update on the file here.
249 */
250 utimes(filedir, NULL);
251 #endif
252
253 /* Clear the cached data */
254 for (i=0; (i < cacheitem->valcount); i++) {
255 cacheitem->updseq[i] = 0;
256 cacheitem->updtime[i] = 0;
257 if (cacheitem->vals[i]) xfree(cacheitem->vals[i]);
258 }
259 cacheitem->valcount = 0;
260
261 return result;
262 }
263
create_and_update_rrd(char * hostname,char * testname,char * classname,char * pagepaths,char * creparams[],void * template)264 static int create_and_update_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *creparams[], void *template)
265 {
266 static int callcounter = 0;
267 struct stat st;
268 int pcount, result;
269 char *updcachekey;
270 xtreePos_t handle;
271 updcacheitem_t *cacheitem = NULL;
272 int pollinterval;
273 strbuffer_t *modifymsg;
274 time_t updtime = 0;
275
276 /* Reset the RRD poll interval */
277 pollinterval = rrdinterval;
278 rrdinterval = DEFAULT_RRD_INTERVAL;
279
280 if ((rrdfn == NULL) || (strlen(rrdfn) == 0)) {
281 errprintf("RRD update for no file\n");
282 return -1;
283 }
284
285 MEMDEFINE(rrdvalues);
286 MEMDEFINE(filedir);
287
288 sprintf(filedir, "%s/%s", rrddir, hostname);
289 if (stat(filedir, &st) == -1) {
290 if (mkdir(filedir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == -1) {
291 errprintf("Cannot create rrd directory %s : %s\n", filedir, strerror(errno));
292 MEMUNDEFINE(filedir);
293 MEMUNDEFINE(rrdvalues);
294 return -1;
295 }
296 }
297 /* Watch out here - "rrdfn" may be very large. */
298 snprintf(filedir, sizeof(filedir)-1, "%s/%s/%s", rrddir, hostname, rrdfn);
299 filedir[sizeof(filedir)-1] = '\0'; /* Make sure it is null terminated */
300
301 /*
302 * Prepare to cache the update. Create the cache tree, and find/create a cache record.
303 * Note: Cache records are persistent, once created they remain in place forever.
304 * Only the update-data is flushed from time to time.
305 */
306 if (updcache_keyofs == -1) {
307 updcache = xtreeNew(strcasecmp);
308 updcache_keyofs = strlen(rrddir);
309 }
310 updcachekey = filedir + updcache_keyofs;
311 handle = xtreeFind(updcache, updcachekey);
312 if (handle == xtreeEnd(updcache)) {
313 if (!template) template = setup_template(creparams);
314 if (!template) {
315 errprintf("BUG: setup_template() returns NULL! host=%s,test=%s,cp[0]=%s, cp[1]=%s\n",
316 hostname, testname,
317 (creparams[0] ? creparams[0] : "NULL"),
318 (creparams[1] ? creparams[1] : "NULL"));
319 return -1;
320 }
321 cacheitem = (updcacheitem_t *)calloc(1, sizeof(updcacheitem_t));
322 cacheitem->key = strdup(updcachekey);
323 cacheitem->tpl = template;
324 xtreeAdd(updcache, cacheitem->key, cacheitem);
325 }
326 else {
327 cacheitem = (updcacheitem_t *)xtreeData(updcache, handle);
328 if (!template) template = cacheitem->tpl;
329 }
330
331 /* If the RRD file doesn't exist, create it immediately */
332 if (stat(filedir, &st) == -1) {
333 char **rrdcreate_params, **rrddefinitions;
334 int rrddefcount, i;
335 char *rrakey = NULL;
336 char stepsetting[10];
337 int havestepsetting = 0, fixcount = 2;
338
339 dbgprintf("Creating rrd %s\n", filedir);
340
341 /* How many parameters did we get? */
342 for (pcount = 0; (creparams[pcount]); pcount++);
343
344 /* Add the RRA definitions to the create parameter set */
345 if (pollinterval != DEFAULT_RRD_INTERVAL) {
346 rrakey = (char *)malloc(strlen(testname) + 10);
347 sprintf(rrakey, "%s/%d", testname, pollinterval);
348 }
349 sprintf(stepsetting, "%d", pollinterval);
350
351 rrddefinitions = get_rrd_definition((rrakey ? rrakey : testname), &rrddefcount);
352 rrdcreate_params = (char **)calloc(4 + pcount + rrddefcount + 1, sizeof(char *));
353 rrdcreate_params[0] = "rrdcreate";
354 rrdcreate_params[1] = filedir;
355
356 /* Is there already a step-setting in the rrddefinitions? */
357 for (i=0; (!havestepsetting && (i < rrddefcount)); i++)
358 havestepsetting = ((strcmp(rrddefinitions[i], "-s") == 0) || (strcmp(rrddefinitions[i], "--step") == 0));
359 if (!havestepsetting) {
360 rrdcreate_params[2] = "-s";
361 rrdcreate_params[3] = stepsetting;
362 fixcount = 4;
363 }
364
365 for (i=0; (i < pcount); i++)
366 rrdcreate_params[fixcount+i] = creparams[i];
367 for (i=0; (i < rrddefcount); i++, pcount++)
368 rrdcreate_params[fixcount+pcount] = rrddefinitions[i];
369
370 if (debug) {
371 for (i = 0; (rrdcreate_params[i]); i++) {
372 dbgprintf("RRD create param %02d: '%s'\n", i, rrdcreate_params[i]);
373 }
374 }
375
376 /*
377 * Ugly! RRDtool uses getopt() for parameter parsing, so
378 * we MUST reset this before every call.
379 */
380 optind = opterr = 0; rrd_clear_error();
381 result = rrd_create(4+pcount, rrdcreate_params);
382 xfree(rrdcreate_params);
383 if (rrakey) xfree(rrakey);
384
385 if (result != 0) {
386 errprintf("RRD error creating %s: %s\n", filedir, rrd_get_error());
387 MEMUNDEFINE(filedir);
388 MEMUNDEFINE(rrdvalues);
389 return 1;
390 }
391 }
392
393 updtime = atoi(rrdvalues);
394 if (cacheitem->valcount > 0) {
395 /* Check for duplicate updates */
396
397 if (cacheitem->updseq[cacheitem->valcount-1] == seq) {
398 /*
399 * This is usually caused by a configuration error,
400 * e.g. two PORT settings in analysis.cfg that
401 * use the same TRACK string.
402 * Can also be two web checks using the same URL, but
403 * with different POST data.
404 */
405 dbgprintf("%s/%s: Error - ignored duplicate update for message sequence %d\n", hostname, rrdfn, seq);
406 MEMUNDEFINE(filedir);
407 MEMUNDEFINE(rrdvalues);
408 return 0;
409 }
410 else if (cacheitem->updtime[cacheitem->valcount-1] > updtime) {
411 dbgprintf("%s/%s: Error - RRD time goes backwards: Now=%d, previous=%d\n", hostname, rrdfn, (int) updtime, (int)cacheitem->updtime[cacheitem->valcount-1]);
412 MEMUNDEFINE(filedir);
413 MEMUNDEFINE(rrdvalues);
414 return 0;
415 }
416 else if (cacheitem->updtime[cacheitem->valcount-1] == updtime) {
417 int identical = (strcmp(rrdvalues, cacheitem->vals[cacheitem->valcount-1]) == 0);
418
419 if (!identical) {
420 int i;
421
422 errprintf("%s/%s: Bug - duplicate RRD data with same timestamp %d, different data\n",
423 hostname, rrdfn, (int) updtime);
424
425 for (i=0; (i < cacheitem->valcount); i++)
426 dbgprintf("Val %d: Seq %d: %s\n", i, cacheitem->updseq[i], cacheitem->vals[i]);
427 dbgprintf("NewVal: Seq %d: %s\n", seq, rrdvalues);
428 }
429 else {
430 dbgprintf("%s/%s: Ignored duplicate (and identical) update timestamped %d\n", hostname, rrdfn, (int) updtime);
431 }
432
433 MEMUNDEFINE(filedir);
434 MEMUNDEFINE(rrdvalues);
435 return 0;
436 }
437 }
438
439
440 /*
441 * Match the RRD data against any DS client-configuration modifiers.
442 */
443 modifymsg = check_rrdds_thresholds(hostname, classname, pagepaths, rrdfn, ((rrdtpldata_t *)template)->dsnames, rrdvalues);
444 if (modifymsg) combo_add(modifymsg);
445
446 /*
447 * See if we want the data to go to an external handler.
448 */
449 if (processorstream) {
450 int i, n;
451
452 n = fprintf(processorstream, "%s %s %s", ((rrdtpldata_t *)template)->template, rrdvalues, hostname);
453 for (i=0; ((n >= 0) && fnparams[i]); i++) n = fprintf(processorstream, " %s", fnparams[i]);
454 if (n >= 0) n = fprintf(processorstream, "\n");
455 if (n >= 0) fflush(processorstream);
456
457 if (n == -1) {
458 errprintf("Ext-processor write failed: %s\n", strerror(errno));
459 shutdown_extprocessor();
460 }
461 }
462
463 /* Are we actually handling the writing of RRD files? */
464 if (no_rrd) return 0;
465
466 /*
467 * We cannot just cache data every time because then after CACHESZ updates
468 * of each RRD, we will flush all of the data at once (all of the caches
469 * fill at the same speed); this would result in huge load-spikes every
470 * rrdinterval*CACHESZ seconds.
471 *
472 * So to smooth the load, we force the update through for every CACHESZ
473 * updates, regardless of how much is in the cache. This gives us a steady
474 * (although slightly higher) load.
475 */
476 if (use_rrd_cache && (++callcounter < CACHESZ)) {
477 if (cacheitem && (cacheitem->valcount < CACHESZ)) {
478 cacheitem->updseq[cacheitem->valcount] = seq;
479 cacheitem->updtime[cacheitem->valcount] = updtime;
480 cacheitem->vals[cacheitem->valcount] = strdup(rrdvalues);
481 cacheitem->valcount += 1;
482 MEMUNDEFINE(filedir);
483 MEMUNDEFINE(rrdvalues);
484 return 0;
485 }
486 }
487 else callcounter = 0;
488
489 /* At this point, we will commit the update to disk */
490 result = flush_cached_updates(cacheitem, rrdvalues);
491 if (result != 0) {
492 char *msg = rrd_get_error();
493
494 if (strstr(msg, "(minimum one second step)") != NULL) {
495 dbgprintf("RRD error updating %s from %s: %s\n",
496 filedir, (senderip ? senderip : "unknown"), msg);
497 }
498 else {
499 errprintf("RRD error updating %s from %s: %s\n",
500 filedir, (senderip ? senderip : "unknown"), msg);
501 }
502
503 MEMUNDEFINE(filedir);
504 MEMUNDEFINE(rrdvalues);
505 return 2;
506 }
507
508 MEMUNDEFINE(filedir);
509 MEMUNDEFINE(rrdvalues);
510
511 return 0;
512 }
513
rrdcacheflushall(void)514 void rrdcacheflushall(void)
515 {
516 xtreePos_t handle;
517 updcacheitem_t *cacheitem;
518
519 if (updcache_keyofs == -1) return; /* No cache */
520
521 for (handle = xtreeFirst(updcache); (handle != xtreeEnd(updcache)); handle = xtreeNext(updcache, handle)) {
522 cacheitem = (updcacheitem_t *) xtreeData(updcache, handle);
523 if (cacheitem->valcount > 0) {
524 sprintf(filedir, "%s%s", rrddir, cacheitem->key);
525 flush_cached_updates(cacheitem, NULL);
526 }
527 }
528 }
529
rrdcacheflushhost(char * hostname)530 void rrdcacheflushhost(char *hostname)
531 {
532 xtreePos_t handle;
533 updcacheitem_t *cacheitem;
534 flushtree_t *flushitem;
535 int keylen;
536 time_t now = gettimer();
537
538 if (updcache_keyofs == -1) return;
539
540 /* If we get a full path for the key, skip the leading rrddir */
541 if (strncmp(hostname, rrddir, updcache_keyofs) == 0) hostname += updcache_keyofs;
542 keylen = strlen(hostname);
543
544 if (!have_flushtree) {
545 flushtree = xtreeNew(strcasecmp);
546 have_flushtree = 1;
547 }
548 handle = xtreeFind(flushtree, hostname);
549 if (handle == xtreeEnd(flushtree)) {
550 flushitem = (flushtree_t *)calloc(1, sizeof(flushtree_t));
551 flushitem->hostname = strdup(hostname);
552 flushitem->flushtime = 0;
553 xtreeAdd(flushtree, flushitem->hostname, flushitem);
554 }
555 else {
556 flushitem = (flushtree_t *) xtreeData(flushtree, handle);
557 }
558
559 if ((flushitem->flushtime + 60) >= now) {
560 dbgprintf("Flush of '%s' skipped, too soon\n", hostname);
561 return;
562 }
563 flushitem->flushtime = now;
564
565 handle = xtreeFirst(updcache);
566 while (handle != xtreeEnd(updcache)) {
567 cacheitem = (updcacheitem_t *) xtreeData(updcache, handle);
568
569 switch (strncasecmp(cacheitem->key, hostname, keylen)) {
570 case 1 :
571 handle = xtreeEnd(updcache); break;
572
573 case 0:
574 if (cacheitem->valcount > 0) {
575 dbgprintf("Flushing cache '%s'\n", cacheitem->key);
576 sprintf(filedir, "%s%s", rrddir, cacheitem->key);
577 flush_cached_updates(cacheitem, NULL);
578 }
579 /* Fall through */
580
581 default:
582 handle = xtreeNext(updcache, handle);
583 break;
584 }
585 }
586 }
587
rrddatasets(char * hostname,char *** dsnames)588 static int rrddatasets(char *hostname, char ***dsnames)
589 {
590 struct stat st;
591
592 int result;
593 char *fetch_params[] = { "rrdfetch", filedir, "AVERAGE", "-s", "-30m", NULL };
594 time_t starttime, endtime;
595 unsigned long steptime, dscount;
596 rrd_value_t *rrddata;
597
598 snprintf(filedir, sizeof(filedir)-1, "%s/%s/%s", rrddir, hostname, rrdfn);
599 filedir[sizeof(filedir)-1] = '\0';
600 if (stat(filedir, &st) == -1) return 0;
601
602 optind = opterr = 0; rrd_clear_error();
603 result = rrd_fetch(5, fetch_params, &starttime, &endtime, &steptime, &dscount, dsnames, &rrddata);
604 if (result == -1) {
605 errprintf("Error while retrieving RRD dataset names from %s: %s\n",
606 filedir, rrd_get_error());
607 return 0;
608 }
609
610 free(rrddata); /* No use for the actual data */
611 return dscount;
612 }
613
614 /* Include all of the sub-modules. */
615 #include "rrd/do_xymongen.c"
616 #include "rrd/do_xymonnet.c"
617 #include "rrd/do_xymonproxy.c"
618 #include "rrd/do_xymond.c"
619 #include "rrd/do_citrix.c"
620 #include "rrd/do_ntpstat.c"
621
622 #include "rrd/do_memory.c" /* Must go before do_la.c */
623 #include "rrd/do_la.c"
624
625 /*
626 * From hobbit-perl-client http://sourceforge.net/projects/hobbit-perl-cl/
627 * version 1.15 Oct. 17 2006 (downloaded on 2008-12-01).
628 *
629 * Include file for netapp.pl dbcheck.pl and beastat.pl scripts
630 * do_fd_lib.c contains some function used by the other library
631 *
632 * Must go before "do_disk.c"
633 */
634 #include "rrd/do_fd_lib.c"
635 #include "rrd/do_netapp.c"
636 #include "rrd/do_beastat.c"
637 #include "rrd/do_dbcheck.c"
638
639
640 #include "rrd/do_disk.c"
641 #include "rrd/do_netstat.c"
642 #include "rrd/do_vmstat.c"
643 #include "rrd/do_iostat.c"
644 #include "rrd/do_ifstat.c"
645
646 #include "rrd/do_apache.c"
647 #include "rrd/do_sendmail.c"
648 #include "rrd/do_mailq.c"
649 #include "rrd/do_iishealth.c"
650 #include "rrd/do_temperature.c"
651
652 #include "rrd/do_net.c"
653
654 #include "rrd/do_ncv.c"
655 #include "rrd/do_external.c"
656 #include "rrd/do_filesizes.c"
657 #include "rrd/do_counts.c"
658 #include "rrd/do_trends.c"
659
660 #include "rrd/do_ifmib.c"
661 #include "rrd/do_snmpmib.c"
662
663 /* z/OS, z/VM, z/VME stuff */
664 #include "rrd/do_paging.c"
665 #include "rrd/do_mdc.c"
666 #include "rrd/do_cics.c"
667 #include "rrd/do_getvis.c"
668 #include "rrd/do_asid.c"
669
670
671 /*
672 * From devmon http://sourceforge.net/projects/devmon/
673 * version 0.3.0 (downloaded on 2008-12-01).
674 */
675 #include "rrd/do_devmon.c"
676
677
update_rrd(char * hostname,char * testname,char * msg,time_t tstamp,char * sender,xymonrrd_t * ldef,char * classname,char * pagepaths)678 void update_rrd(char *hostname, char *testname, char *msg, time_t tstamp, char *sender, xymonrrd_t *ldef, char *classname, char *pagepaths)
679 {
680 char *id;
681
682 MEMDEFINE(rrdvalues);
683
684 if (ldef) id = ldef->xymonrrdname; else id = testname;
685 senderip = sender;
686
687 if (strcmp(id, "bbgen") == 0) do_xymongen_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
688 else if (strcmp(id, "xymongen") == 0) do_xymongen_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
689 else if (strcmp(id, "bbtest") == 0) do_xymonnet_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
690 else if (strcmp(id, "xymonnet") == 0) do_xymonnet_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
691 else if (strcmp(id, "bbproxy") == 0) do_xymonproxy_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
692 else if (strcmp(id, "xymonproxy") == 0) do_xymonproxy_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
693 else if (strcmp(id, "hobbitd") == 0) do_xymond_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
694 else if (strcmp(id, "xymond") == 0) do_xymond_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
695 else if (strcmp(id, "citrix") == 0) do_citrix_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
696 else if (strcmp(id, "ntpstat") == 0) do_ntpstat_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
697
698 else if (strcmp(id, "la") == 0) do_la_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
699 else if (strcmp(id, "disk") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
700 else if (strcmp(id, "memory") == 0) do_memory_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
701 else if (strcmp(id, "netstat") == 0) do_netstat_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
702 else if (strcmp(id, "vmstat") == 0) do_vmstat_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
703 else if (strcmp(id, "iostat") == 0) do_iostat_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
704 else if (strcmp(id, "ifstat") == 0) do_ifstat_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
705
706 /* These two come from the filerstats2bb.pl script. The reports are in disk-format */
707 else if (strcmp(id, "inode") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
708 else if (strcmp(id, "qtree") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
709
710 else if (strcmp(id, "apache") == 0) do_apache_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
711 else if (strcmp(id, "sendmail") == 0) do_sendmail_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
712 else if (strcmp(id, "mailq") == 0) do_mailq_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
713 else if (strcmp(id, "iishealth") == 0) do_iishealth_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
714 else if (strcmp(id, "temperature") == 0) do_temperature_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
715
716 else if (strcmp(id, "ncv") == 0) do_ncv_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
717 else if (strcmp(id, "tcp") == 0) do_net_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
718
719 else if (strcmp(id, "filesizes") == 0) do_filesizes_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
720 else if (strcmp(id, "proccounts") == 0) do_counts_rrd("processes", hostname, testname, classname, pagepaths, msg, tstamp);
721 else if (strcmp(id, "portcounts") == 0) do_counts_rrd("ports", hostname, testname, classname, pagepaths, msg, tstamp);
722 else if (strcmp(id, "linecounts") == 0) do_derives_rrd("lines", hostname, testname, classname, pagepaths, msg, tstamp);
723 else if (strcmp(id, "deltacounts") == 0) do_counts_rrd("deltalines", hostname, testname, classname, pagepaths, msg, tstamp);
724 else if (strcmp(id, "trends") == 0) do_trends_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
725
726 else if (strcmp(id, "ifmib") == 0) do_ifmib_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
727 else if (is_snmpmib_rrd(id)) do_snmpmib_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
728
729 /* z/OS, z/VSE, z/VM from Rich Smrcina */
730 else if (strcmp(id, "paging") == 0) do_paging_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
731 else if (strcmp(id, "mdc") == 0) do_mdc_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
732 else if (strcmp(id, "cics") == 0) do_cics_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
733 else if (strcmp(id, "getvis") == 0) do_getvis_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
734 else if (strcmp(id, "maxuser") == 0) do_asid_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
735 else if (strcmp(id, "nparts") == 0) do_asid_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
736
737 /*
738 * These are from the hobbit-perl-client
739 * NetApp check for netapp.pl, dbcheck.pl and beastat.pl scripts
740 */
741 else if (strcmp(id, "xtstats") == 0) do_netapp_extrastats_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
742 else if (strcmp(id, "quotas") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
743 else if (strcmp(id, "snapshot") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
744 else if (strcmp(id, "TblSpace") == 0) do_disk_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
745 else if (strcmp(id, "stats") == 0) do_netapp_stats_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
746 else if (strcmp(id, "ops") == 0) do_netapp_ops_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
747 else if (strcmp(id, "cifs") == 0) do_netapp_cifs_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
748 else if (strcmp(id, "snaplist") == 0) do_netapp_snaplist_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
749 else if (strcmp(id, "snapmirr") == 0) do_netapp_snapmirror_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
750 else if (strcmp(id, "HitCache") == 0) do_dbcheck_hitcache_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
751 else if (strcmp(id, "Session") == 0) do_dbcheck_session_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
752 else if (strcmp(id, "RollBack") == 0) do_dbcheck_rb_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
753 else if (strcmp(id, "InvObj") == 0) do_dbcheck_invobj_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
754 else if (strcmp(id, "MemReq") == 0) do_dbcheck_memreq_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
755 else if (strcmp(id, "JVM") == 0) do_beastat_jvm_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
756 else if (strcmp(id, "JMS") == 0) do_beastat_jms_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
757 else if (strcmp(id, "JTA") == 0) do_beastat_jta_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
758 else if (strcmp(id, "ExecQueue") == 0) do_beastat_exec_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
759 else if (strcmp(id, "JDBCConn") == 0) do_beastat_jdbc_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
760
761 /*
762 * This is from the devmon SNMP collector
763 */
764 else if (strcmp(id, "devmon") == 0) do_devmon_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
765
766 else if (extids && exthandler) {
767 int i;
768
769 for (i=0; (extids[i] && strcmp(extids[i], id)); i++) ;
770
771 if (extids[i]) do_external_rrd(hostname, testname, classname, pagepaths, msg, tstamp);
772 }
773
774 senderip = NULL;
775
776 MEMUNDEFINE(rrdvalues);
777 }
778
779