int do_cics_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *pr; char *fn = NULL; int numtrans; float dsapct, edsapct; char cicsappl[9], rrdfn[20]; pr=(strstr(msg, "Appl")); if (!pr) { return 0; } pr=(strstr(pr, "\n")); if (pr) { pr += 1; pr = strtok(pr, "\n"); while (pr != NULL) { sscanf(pr, "%s %d %f %f", cicsappl, &numtrans, &dsapct, &edsapct); sprintf(rrdfn, "cics.%-s.rrd", cicsappl); setupfn(rrdfn, fn); sprintf(rrdvalues, "%d:%d", (int)tstamp, numtrans); create_and_update_rrd(hostname, testname, classname, pagepaths, cicsntrans_params, cics_tpl); sprintf(rrdfn, "dsa.%-s.rrd", cicsappl); setupfn(rrdfn, fn); sprintf(rrdvalues, "%d:%d:%d", (int)tstamp, (int)dsapct, (int)edsapct); create_and_update_rrd(hostname, testname, classname, pagepaths, cicsdsa_params, cics_tpl); pr = strtok(NULL, "\n"); } } return 0; }
int do_beastat_jms_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *beastat_jms_params[] = { "DS:CurrConn:GAUGE:600:0:U", "DS:HighConn:GAUGE:600:0:U", "DS:TotalConn:DERIVE:600:0:U", "DS:CurrJMSSrv:GAUGE:600:0:U", "DS:HighJMSSrv:GAUGE:600:0:U", "DS:TotalJMSSrv:DERIVE:600:0:U", NULL }; static void *beastat_jms_tpl = NULL; unsigned long conncurr=0, connhigh=0, conntotal=0, jmscurr=0, jmshigh=0, jmstotal=0; dbgprintf("beastat: host %s test %s\n",hostname, testname); if (strstr(msg, "beastat.pl")) { setupfn("%s.rrd",testname); if (beastat_jms_tpl == NULL) beastat_jms_tpl = setup_template(beastat_jms_params); conncurr=get_long_data(msg, "ConnectionsCurrentCount"); connhigh=get_long_data(msg,"ConnectionsHighCount"); conntotal=get_long_data(msg,"ConnectionsTotalCount"); jmscurr=get_long_data(msg,"JMSServersCurrentCount"); jmshigh=get_long_data(msg,"JMSServersHighCount"); jmstotal=get_long_data(msg,"JMSServersTotalCount"); dbgprintf("beastat: host %s test %s conncurr %ld connhigh %ld conntotal %ld\n", hostname, testname, conncurr, connhigh, conntotal); dbgprintf("beastat: host %s test %s jmscurr %ld jmshigh %ld jmstotal %ld\n", hostname, testname, jmscurr, jmshigh,jmstotal); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld:%ld:%ld:%ld:%ld", (int) tstamp, conncurr, connhigh, conntotal, jmscurr, jmshigh, jmstotal); create_and_update_rrd(hostname, testname, classname, pagepaths, beastat_jms_params, beastat_jms_tpl); } return 0; }
int do_filesizes_rrd(char *hostname, char *testname, char *msg, time_t tstamp) { char *boln, *eoln; if (filesize_tpl == NULL) filesize_tpl = setup_template(filesize_params); boln = strchr(msg, '\n'); if (boln) boln++; while (boln && *boln) { char *fn, *szstr = NULL; eoln = strchr(boln, '\n'); if (eoln) *eoln = '\0'; fn = strtok(boln, ":"); if (fn) szstr = strtok(NULL, ":"); if (fn && szstr) { char *p; for (p=strchr(fn, '/'); (p); p = strchr(p, '/')) *p = ','; setupfn("filesizes.%s.rrd", fn); sprintf(rrdvalues, "%d:%s", (int)tstamp, szstr); create_and_update_rrd(hostname, rrdfn, filesize_params, filesize_tpl); } boln = (eoln ? eoln+1 : NULL); } return 0; }
int do_paging_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *pr; char *fn = NULL; int pagerate, xstore, migrate; if (paging_tpl == NULL) paging_tpl = setup_template(paging_params); pr=(strstr(msg, "Rate")); if (pr) { pr += 5; sscanf(pr, "%d per", &pagerate); setupfn("paging.pagerate.rrd", fn); sprintf(rrdvalues, "%d:%d", (int)tstamp, pagerate); create_and_update_rrd(hostname, testname, classname, pagepaths, paging_params, paging_tpl); if (strstr(msg, "z/VM")) { /* Additional handling for z/VM */ pr=strstr(msg,"XSTORE-"); if (pr) { /* Extract values if we find XSTORE in results of 'IND' command */ pr += 7; /* Add 7 to get past literal (XSTORE). */ sscanf(pr, "%d/SEC", &xstore); pr=strstr(msg,"MIGRATE-"); pr += 8; /* Add 8 to get past literal (MIGRATE). */ sscanf(pr, "%d/SEC", &migrate); setupfn("paging.xstore.rrd", fn); sprintf(rrdvalues, "%d:%d", (int)tstamp, xstore); create_and_update_rrd(hostname, testname, classname, pagepaths, paging_params, paging_tpl); setupfn("paging.migrate.rrd", fn); sprintf(rrdvalues, "%d:%d", (int)tstamp, migrate); create_and_update_rrd(hostname, testname, classname, pagepaths, paging_params, paging_tpl); } } } return 0; }
int do_beastat_jta_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *beastat_jta_params[] = { "DS:ActiveTrans:GAUGE:600:0:U", "DS:SecondsActive:DERIVE:600:0:U", "DS:TransAbandoned:DERIVE:600:0:U", "DS:TransCommitted:DERIVE:600:0:U", "DS:TransHeuristics:DERIVE:600:0:U", "DS:TransRBackApp:DERIVE:600:0:U", "DS:TransRBackResource:DERIVE:600:0:U", "DS:TransRBackSystem:DERIVE:600:0:U", "DS:TransRBackTimeout:DERIVE:600:0:U", "DS:TransRBack:DERIVE:600:0:U", "DS:TransTotCount:DERIVE:600:0:U", NULL }; static void *beastat_jta_tpl = NULL; unsigned long heapfree=0, heapsize=0; unsigned long acttrans=0, secact=0, trab=0, trcomm=0, trheur=0, totot=0; unsigned long trrbapp=0, trrbres=0, trrbsys=0, trrbto=0, trrb=0, trtot=0; dbgprintf("beastat: host %s test %s\n",hostname, testname); if (strstr(msg, "beastat.pl")) { setupfn("%s.rrd",testname); if (beastat_jta_tpl == NULL) beastat_jta_tpl = setup_template(beastat_jta_params); acttrans=get_long_data(msg,"ActiveTransactionsTotalCount"); secact=get_long_data(msg,"SecondsActiveTotalCount"); trab=get_long_data(msg,"TransactionAbandonedTotalCount"); trcomm=get_long_data(msg,"TransactionCommittedTotalCount"); trheur=get_long_data(msg,"TransactionHeuristicsTotalCount"); trrbapp=get_long_data(msg,"TransactionRolledBackAppTotalCount"); trrbres=get_long_data(msg,"TransactionRolledBackResourceTotalCount"); trrbsys=get_long_data(msg,"TransactionRolledBackSystemTotalCount"); trrbto=get_long_data(msg,"TransactionRolledBackTimeoutTotalCount"); trrb=get_long_data(msg,"TransactionRolledBackTotalCount"); trtot=get_long_data(msg,"TransactionTotalCount"); dbgprintf("beastat: host %s test %s acttrans %ld secact %ld\n", hostname, testname, acttrans, secact); dbgprintf("beastat: host %s test %s TRANS: aband %ld comm %ld heur %ld total\n", hostname, testname, trab, trcomm, trheur, trtot); dbgprintf("beastat: host %s test %s RB: app %ld res %ld sys %ld timout %ld total %ld\n", hostname, testname, trrbapp, trrbres, trrbsys, trrbto, trrb); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld", (int) tstamp, acttrans, secact, trab, trcomm, trheur, trrbapp, trrbres, trrbsys, trrbto, trrb, trtot); create_and_update_rrd(hostname, testname, classname, pagepaths, beastat_jta_params, beastat_jta_tpl); } return 0; }
int do_asid_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char *p; p=(strstr(msg, "Maxuser")); if (p) { long maxuser, maxufree, maxuused, rsvtstrt, rsvtfree, rsvtused, rsvnonr, rsvnfree, rsvnused; float maxupct, rsvtpct, rsvnpct; sscanf(p, "Maxuser: %ld Free: %ld Used: %ld %f", &maxuser, &maxufree, &maxuused, &maxupct); p=(strstr(p, "RSVTSTRT")); sscanf(p, "RSVTSTRT: %ld Free: %ld Used: %ld %f", &rsvtstrt, &rsvtfree, &rsvtused, &rsvtpct); p=(strstr(p, "RSVNONR")); sscanf(p, "RSVNONR: %ld Free: %ld Used: %ld %f", &rsvnonr, &rsvnfree, &rsvnused, &rsvnpct); setupfn2("%s.%s.rrd", "maxuser", "maxuser"); sprintf(rrdvalues, "%d:%d", (int)tstamp, (int)maxupct); create_and_update_rrd(hostname, testname, classname, pagepaths, asid_params, asid_tpl); setupfn2("%s.%s.rrd", "maxuser", "rsvtstrt"); sprintf(rrdvalues, "%d:%d", (int)tstamp, (int)rsvtpct); create_and_update_rrd(hostname, testname, classname, pagepaths, asid_params, asid_tpl); setupfn2("%s.%s.rrd", "maxuser", "rsvnonr"); sprintf(rrdvalues, "%d:%d", (int)tstamp, (int)rsvnpct); create_and_update_rrd(hostname, testname, classname, pagepaths, asid_params, asid_tpl); } p=(strstr(msg, "Nparts")); if (p) { char *fn = NULL; long nparts, partfree, partused; float partupct; sscanf(p, "Nparts: %ld Free: %ld Used: %ld %f", &nparts, &partfree, &partused, &partupct); setupfn("nparts.rrd", fn); sprintf(rrdvalues, "%d:%d", (int)tstamp, (int)partupct); create_and_update_rrd(hostname, testname, classname, pagepaths, asid_params, asid_tpl); } return 0; }
int do_citrix_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *citrix_params[] = { "DS:users:GAUGE:600:0:U", NULL }; static void *citrix_tpl = NULL; char *p; int users; if (citrix_tpl == NULL) citrix_tpl = setup_template(citrix_params); p = strstr(msg, " users active\n"); while (p && (p > msg) && (*p != '\n')) p--; if (p && (sscanf(p+1, "\n%d users active\n", &users) == 1)) { setupfn("%s.rrd", "citrix"); sprintf(rrdvalues, "%d:%d", (int)tstamp, users); return create_and_update_rrd(hostname, testname, classname, pagepaths, citrix_params, citrix_tpl); } return 0; }
int do_beastat_jvm_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *beastat_jvm_params[] = { "DS:HeapFreeCurrent:GAUGE:600:0:U", "DS:HeapSizeCurrent:GAUGE:600:0:U", NULL }; static void *beastat_jvm_tpl = NULL; unsigned long heapfree=0, heapsize=0; dbgprintf("beastat: host %s test %s\n",hostname, testname); if (strstr(msg, "beastat.pl")) { setupfn("%s.rrd",testname); if (beastat_jvm_tpl == NULL) beastat_jvm_tpl = setup_template(beastat_jvm_params); heapfree=get_long_data(msg, "HeapFreeCurrent"); heapsize=get_long_data(msg,"HeapSizeCurrent"); dbgprintf("beastat: host %s test %s heapfree %ld heapsize %ld\n", hostname, testname, heapfree, heapsize); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%ld:%ld", (int) tstamp, heapfree, heapsize); create_and_update_rrd(hostname, testname, classname, pagepaths, beastat_jvm_params, beastat_jvm_tpl); } return 0; }
int do_bbproxy_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *bbproxy_params[] = { "DS:runtime:GAUGE:600:0:U", NULL }; static void *bbproxy_tpl = NULL; char *p; float runtime; if (bbproxy_tpl == NULL) bbproxy_tpl = setup_template(bbproxy_params); p = strstr(msg, "Average queue time"); if (p && (sscanf(p, "Average queue time : %f", &runtime) == 1)) { if (strcmp("bbproxy", testname) != 0) { setupfn2("%s.%s.rrd", "bbproxy", testname); } else { setupfn("%s.rrd", "bbproxy"); } sprintf(rrdvalues, "%d:%.2f", (int) tstamp, runtime); return create_and_update_rrd(hostname, testname, classname, pagepaths, bbproxy_params, bbproxy_tpl); } return 0; }
int do_external_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { pid_t childpid; dbgprintf("-> do_external(%s, %s)\n", hostname, testname); childpid = fork(); if (childpid == 0) { FILE *fd; char fn[PATH_MAX]; enum { R_DEFS, R_FN, R_DATA, R_NEXT } pstate; FILE *extfd; char extcmd[2*PATH_MAX]; strbuffer_t *inbuf; char *p; char **params = NULL; int paridx = 0; pid_t mypid = getpid(); MEMDEFINE(fn); MEMDEFINE(extcmd); sprintf(fn, "%s/rrd_msg_%d", xgetenv("XYMONTMP"), (int) getpid()); dbgprintf("%09d : Saving msg to file %s\n", (int)mypid, fn); fd = fopen(fn, "w"); if (fd == NULL) { errprintf("Cannot create temp file %s\n", fn); exit(1); } if (fwrite(msg, strlen(msg), 1, fd) != 1) { errprintf("Error writing to file %s: %s\n", fn, strerror(errno)); exit(1) ; } if (fclose(fd)) errprintf("Error closing file %s: %s\n", fn, strerror(errno)); /* * Disable the RRD update cache. * We cannot use the cache, because this child * process terminates without flushing the cache, * and it cannot feed the update-data back to the * parent process which owns the cache. So using * an external handler means the updates will be * sync'ed to disk immediately. * * NB: It is OK to do this now and not re-enable it, * since we're running in the external helper * child process - so this only affects the current * update. * * Thanks to Graham Nayler for the analysis. */ use_rrd_cache = 0; inbuf = newstrbuffer(0); /* Now call the external helper */ sprintf(extcmd, "%s %s %s %s", exthandler, hostname, testname, fn); dbgprintf("%09d : Calling helper script %s\n", (int)mypid, extcmd); extfd = popen(extcmd, "r"); if (extfd) { pstate = R_DEFS; initfgets(extfd); while (unlimfgets(inbuf, extfd)) { p = strchr(STRBUF(inbuf), '\n'); if (p) *p = '\0'; dbgprintf("%09d : Helper input '%s'\n", (int)mypid, STRBUF(inbuf)); if (STRBUFLEN(inbuf) == 0) continue; if (pstate == R_NEXT) { /* After doing one set of data, allow script to re-use the same DS defs */ if (strncasecmp(STRBUF(inbuf), "DS:", 3) == 0) { /* New DS definitions, scratch the old ones */ if (params) { for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]); xfree(params); params = NULL; } pstate = R_DEFS; } else pstate = R_FN; } switch (pstate) { case R_DEFS: if (params == NULL) { params = (char **)calloc(1, sizeof(char *)); paridx = 0; } if (strncasecmp(STRBUF(inbuf), "DS:", 3) == 0) { /* Dataset definition */ params[paridx] = strdup(STRBUF(inbuf)); paridx++; params = (char **)realloc(params, (1 + paridx)*sizeof(char *)); params[paridx] = NULL; break; } else { /* No more DS defs */ pstate = R_FN; } /* Fall through */ case R_FN: setupfn("%s", STRBUF(inbuf)); pstate = R_DATA; break; case R_DATA: snprintf(rrdvalues, sizeof(rrdvalues)-1, "%d:%s", (int)tstamp, STRBUF(inbuf)); rrdvalues[sizeof(rrdvalues)-1] = '\0'; create_and_update_rrd(hostname, testname, classname, pagepaths, params, NULL); pstate = R_NEXT; break; case R_NEXT: /* Should not happen */ break; } } pclose(extfd); } else { errprintf("Pipe open of RRD handler failed: %s\n", strerror(errno)); } if (params) { for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]); xfree(params); } dbgprintf("%09d : Unlinking temp file\n", (int)mypid); unlink(fn); freestrbuffer(inbuf); exit(0); } else if (childpid > 0) { /* Parent continues */ } else { errprintf("Fork failed in RRD handler: %s\n", strerror(errno)); } dbgprintf("<- do_external(%s, %s)\n", hostname, testname); return 0; }
int do_la_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *la_params[] = { "DS:la:GAUGE:600:U:U", NULL }; static void *la_tpl = NULL; static char *clock_params[] = { "DS:la:GAUGE:600:U:U", NULL }; /* "la" is a misnomer, but to stay compatiable with existing RRD files */ static void *clock_tpl = NULL; static pcre *as400_exp = NULL; static pcre *zVM_exp = NULL; static time_t starttime = 0; char *p, *eoln = NULL; int gotusers=0, gotprocs=0, gotload=0, gotclock=0; int users=0, procs=0, load=0, clockdiff=0; time_t now = getcurrenttime(NULL); if (la_tpl == NULL) la_tpl = setup_template(la_params); if (clock_tpl == NULL) clock_tpl = setup_template(clock_params); if (starttime == 0) starttime = now; if (strstr(msg, "bb-xsnmp")) { /* * bb-xsnmp.pl script output. * * green Tue Apr 5 12:57:37 2005 up: 254.58 days, CPU Usage= 9% * * &green CPU Time in Busy Mode: 9% * &green CPU Time in Idle Mode: 91% * * &yellow CPU Usage Threshold: 90% * &red CPU Usage Threshold: 95% * * <!-- Enterprise: netapp , Version: 6.42 --> * bb-xsnmp.pl Version: 1.78 */ p = strstr(msg, "CPU Usage="); if (p) { p += strlen("CPU Usage="); gotload = 1; load = atoi(p); } goto done_parsing; } else if (strstr(msg, "z/VM") || strstr(msg, "VSE/ESA") || strstr(msg, "z/VSE") || strstr(msg, "z/OS")) { /* z/VM cpu message. Looks like this, from Rich Smrcina (client config mode): * green 5 Apr 2005 20:07:34 CPU Utilization 7% z/VM Version 4 Release 4.0, service level 0402 (32-bit) AVGPROC-007% 01 * VSE/ESA or z/VSE cpu message. * VSE/ESA 2.7.2 cr IPLed on ... * or * z/VSE 3.1.1 cr IPLed on ... * In server (centralized) config mode or for z/OS (which is centralized config only) * the operating system name is part of the message (as in the tests above). */ int ovector[30]; char w[100]; int res; if (zVM_exp == NULL) { const char *errmsg = NULL; int errofs = 0; zVM_exp = pcre_compile(".* CPU Utilization *([0-9]+)%", PCRE_CASELESS, &errmsg, &errofs, NULL); } res = pcre_exec(zVM_exp, NULL, msg, strlen(msg), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (res >= 0) { /* We have a match - pick up the data. */ *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 1, w, sizeof(w)); if (strlen(w)) { load = atoi(w); gotload = 1; } } goto done_parsing; } eoln = strchr(msg, '\n'); if (eoln) *eoln = '\0'; p = strstr(msg, "up: "); if (!p) p = strstr(msg, "Uptime:"); /* Netapp filerstats2bb script */ if (!p) p = strstr(msg, "uptime:"); if (p) { /* First line of cpu report, contains "up: 159 days, 1 users, 169 procs, load=21" */ p = strchr(p, ','); if (p) { gotusers = (sscanf(p, ", %d users", &users) == 1); p = strchr(p+1, ','); } if (p) { gotprocs = (sscanf(p, ", %d procs", &procs) == 1); p = strchr(p+1, ','); } /* * Load can be either * - "load=xx%" (Windows) * - "load=xx.xx" (Unix, DISPREALLOADAVG=TRUE) * - "load=xx" (Unix, DISPREALLOADAVG=FALSE) * * We want the load in percent (Windows), or LA*100 (Unix). */ p = strstr(msg, "load="); if (p) { p += 5; if (strchr(p, '%')) { gotload = 1; load = atoi(p); } else if (strchr(p, '.')) { gotload = 1; load = 100*atoi(p); /* Find the decimal part, and cut off at 2 decimals */ p = strchr(p, '.'); if (strlen(p) > 3) *(p+3) = '\0'; load += atoi(p+1); } else { gotload = 1; load = atoi(p); } } } else { /* * No "uptime" in message - could be from an AS/400. They look like this: * green March 21, 2005 12:33:24 PM EST deltacdc 108 users 45525 jobs(126 batch,0 waiting for message), load=26% */ int ovector[30]; char w[100]; int res; if (as400_exp == NULL) { const char *errmsg = NULL; int errofs = 0; as400_exp = pcre_compile(".* ([0-9]+) users ([0-9]+) jobs.* load=([0-9]+)\\%", PCRE_CASELESS, &errmsg, &errofs, NULL); } res = pcre_exec(as400_exp, NULL, msg, strlen(msg), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (res >= 0) { /* We have a match - pick up the AS/400 data. */ *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 1, w, sizeof(w)); if (strlen(w)) { users = atoi(w); gotusers = 1; } *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 3, w, sizeof(w)); if (strlen(w)) { load = atoi(w); gotload = 1; } } } done_parsing: if (eoln) *eoln = '\n'; p = strstr(msg, "System clock is "); if (p) { if (sscanf(p, "System clock is %d seconds off", &clockdiff) == 1) gotclock = 1; } if (!gotload) { /* See if it's a report from the ciscocpu.pl script. */ p = strstr(msg, "<br>CPU 5 min average:"); if (p) { /* It reports in % cpu utilization */ p = strchr(p, ':'); load = atoi(p+1); gotload = 1; } } if (gotload) { setupfn("%s.rrd", "la"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, load); create_and_update_rrd(hostname, testname, classname, pagepaths, la_params, la_tpl); } if (gotprocs) { setupfn("%s.rrd", "procs"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, procs); create_and_update_rrd(hostname, testname, classname, pagepaths, la_params, la_tpl); } if (gotusers) { setupfn("%s.rrd", "users"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, users); create_and_update_rrd(hostname, testname, classname, pagepaths, la_params, la_tpl); } if (gotclock) { setupfn("%s.rrd", "clock"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, clockdiff); create_and_update_rrd(hostname, testname, classname, pagepaths, clock_params, clock_tpl); } /* * If we have run for less than 6 minutes, drop the memory updates here. * We want to be sure not to use memory statistics from the CPU report * if there is a memory add-on sending a separate memory statistics */ if ((now - starttime) < 360) return 0; if (!memhosts_init || (xtreeFind(memhosts, hostname) == xtreeEnd(memhosts))) { /* Pick up memory statistics */ int found, overflow, realuse, swapuse; long long phystotal, physavail, pagetotal, pageavail; found = overflow = realuse = swapuse = 0; phystotal = physavail = pagetotal = pageavail = 0; p = strstr(msg, "Total Physical memory:"); if (p) { phystotal = str2ll(strchr(p, ':') + 1, NULL); if (phystotal != LONG_MAX) found++; else overflow++; } if (found == 1) { p = strstr(msg, "Available Physical memory:"); if (p) { physavail = str2ll(strchr(p, ':') + 1, NULL); if (physavail != LONG_MAX) found++; else overflow++; } } if (found == 2) { p = strstr(msg, "Total PageFile size:"); if (p) { pagetotal = str2ll(strchr(p, ':') + 1, NULL); if (pagetotal != LONG_MAX) found++; else overflow++; } } if (found == 3) { p = strstr(msg, "Available PageFile size:"); if (p) { pageavail = str2ll(strchr(p, ':') + 1, NULL); if (pageavail != LONG_MAX) found++; else overflow++; } } if (found == 4) { if (!phystotal || !pagetotal) { errprintf("Host %s cpu report had 0 total physical/pagefile memory listed\n", hostname); return 0; } phystotal = phystotal / 100; pagetotal = pagetotal / 100; realuse = 100 - (physavail / phystotal); swapuse = 100 - (pageavail / pagetotal); do_memory_rrd_update(tstamp, hostname, testname, classname, pagepaths, realuse, swapuse, -1); } else if (overflow) { errprintf("Host %s cpu report overflows in memory usage calculation\n", hostname); } } return 0; }
int do_ncv_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { char **params = NULL; int paridx; char dsdef[1024]; /* destination DS syntax for rrd engine */ char *l, *name, *val; char *envnam; char *dstypes = NULL; /* contain NCV_testname value */ int split_ncv = 0; int dslen; sprintf(rrdvalues, "%d", (int)tstamp); params = (char **)calloc(1, sizeof(char *)); paridx = 0; /* Get the NCV_* or SPLITNCV_* environment setting */ envnam = (char *)malloc(9 + strlen(testname) + 1); sprintf(envnam, "SPLITNCV_%s", testname); l = getenv(envnam); if (l) { split_ncv = 1; dslen = 200; } else { split_ncv = 0; dslen = 19; setupfn("%s.rrd", testname); sprintf(envnam, "NCV_%s", testname); l = getenv(envnam); } if (l) { dstypes = (char *)malloc(strlen(l)+3); sprintf(dstypes, ",%s,", l); } xfree(envnam); l = strchr(msg, '\n'); if (l) l++; while (l && *l && strncmp(l, "@@\n", 3)) { name = val = NULL; l += strspn(l, " \t\n"); if (*l) { /* See if this line contains a '=' or ':' sign */ name = l; l += strcspn(l, ":=\n"); if (*l) { if (( *l == '=') || (*l == ':')) { *l = '\0'; l++; } else { /* No marker, so skip this line */ name = NULL; } } else break; /* We've hit the end of the message */ } /* Skip any color marker "&COLOR " in front of the ds name */ if (name && (*name == '&')) { name++; name += strspn(name, "abcdefghijklmnopqrstuvwxyz"); name += strspn(name, " \t"); if (*name == '\0') name = NULL; } if (name) { val = l + strspn(l, " \t"); /* Find the end of the value string */ l = val; if ((*l == '-') || (*l == '+')) l++; /* Pass leading sign */ l += strspn(l, "0123456789.+-"); /* and the numbers. */ if( *val ) { int iseol = (*l == '\n'); *l = '\0'; if (!iseol) { /* If extra data after the value, skip to end of line */ l = strchr(l+1, '\n'); if (l) l++; } else { l++; } } else break; /* No value data */ } if (name && val && *val) { char *endptr; strtod(val, &endptr); if (isspace((int)*endptr) || (*endptr == '\0')) { char dsname[250]; /* name of ncv in status message (with space and all) */ char dskey[252]; /* name of final DS key (stripped) */ char *dstype = NULL; /* type of final DS */ char *inp; int outidx = 0; /* val contains a valid number */ /* rrdcreate(1) says: ds must be in the set [a-zA-Z0-9_] ... */ for (inp=name,outidx=0; (*inp && (outidx < dslen)); inp++) { if ( ((*inp >= 'A') && (*inp <= 'Z')) || ((*inp >= 'a') && (*inp <= 'z')) || ((*inp >= '0') && (*inp <= '9')) ) { dsname[outidx++] = *inp; } /* ... however, for split ncv, we replace anything else */ /* with an underscore, compacting successive invalid */ /* characters into a single one */ else if (split_ncv && ((outidx == 0) || (dsname[outidx - 1] != '_'))) { dsname[outidx++] = '_'; } } if ((outidx > 0) && (dsname[outidx-1] == '_')) { dsname[outidx-1] = '\0'; } else { dsname[outidx] = '\0'; } sprintf(dskey, ",%s:", dsname); if (split_ncv) setupfn2("%s,%s.rrd", testname, dsname); if (dstypes) { dstype = strstr(dstypes, dskey); if (!dstype) { strcpy(dskey, ",*:"); dstype = strstr(dstypes, dskey); } } if (dstype) { /* if ds type is forced */ char *p; dstype += strlen(dskey); p = strchr(dstype, ','); if (p) *p = '\0'; if(split_ncv) { sprintf(dsdef, "DS:lambda:%s:600:U:U", dstype); } else { sprintf(dsdef, "DS:%s:%s:600:U:U", dsname, dstype); } if (p) *p = ','; } else { /* nothing specified in the environnement, and no '*:' default */ if(split_ncv) { strcpy(dsdef, "DS:lambda:DERIVE:600:U:U"); } else { sprintf(dsdef, "DS:%s:DERIVE:600:U:U", dsname); } } if (!dstype || (strncasecmp(dstype, "NONE", 4) != 0)) { /* if we have something */ params[paridx] = strdup(dsdef); paridx++; params = (char **)realloc(params, (1 + paridx)*sizeof(char *)); params[paridx] = NULL; sprintf(rrdvalues+strlen(rrdvalues), ":%s", val); } } if (split_ncv && (paridx > 0)) { create_and_update_rrd(hostname, testname, classname, pagepaths, params, NULL); /* We've created one RRD, so reset the params for the next one */ for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]); paridx = 0; params[0] = NULL; sprintf(rrdvalues, "%d", (int)tstamp); } } } /* end of while */ if (!split_ncv && params[0]) create_and_update_rrd(hostname, testname, classname, pagepaths, params, NULL); for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]); xfree(params); if (dstypes) xfree(dstypes); return 0; }
int do_net_rrd(char *hostname, char *testname, char *msg, time_t tstamp) { static char *bbnet_params[] = { "rrdcreate", rrdfn, "DS:sec:GAUGE:600:0:U", rra1, rra2, rra3, rra4, NULL }; static char *bbnet_tpl = NULL; char *p; float seconds; if (bbnet_tpl == NULL) bbnet_tpl = setup_template(bbnet_params); if (strcmp(testname, "http") == 0) { char *line1, *url = NULL, *eoln; line1 = msg; while ((line1 = strchr(line1, '\n')) != NULL) { line1++; /* Skip the newline */ eoln = strchr(line1, '\n'); if (eoln) *eoln = '\0'; if ( (strncmp(line1, "&green", 6) == 0) || (strncmp(line1, "&yellow", 7) == 0) || (strncmp(line1, "&red", 4) == 0) ) { p = strstr(line1, "http"); if (p) { url = xstrdup(p); p = strchr(url, ' '); if (p) *p = '\0'; } } else if (url && ((p = strstr(line1, "Seconds:")) != NULL) && (sscanf(p, "Seconds: %f", &seconds) == 1)) { char *urlfn = url; if (strncmp(urlfn, "http://", 7) == 0) urlfn += 7; p = urlfn; while ((p = strchr(p, '/')) != NULL) *p = ','; setupfn("tcp.http.%s.rrd", urlfn); sprintf(rrdvalues, "%d:%.2f", (int)tstamp, seconds); create_and_update_rrd(hostname, rrdfn, bbnet_params, bbnet_tpl); xfree(url); url = NULL; } if (eoln) *eoln = '\n'; } if (url) xfree(url); } else if (strcmp(testname, xgetenv("PINGCOLUMN")) == 0) { /* * Ping-tests, possibly using fping. */ char *tmod = "ms"; if ((p = strstr(msg, "time=")) != NULL) { /* Standard ping, reports ".... time=0.2 ms" */ seconds = atof(p+5); tmod = p + 5; tmod += strspn(tmod, "0123456789. "); } else if ((p = strstr(msg, "alive")) != NULL) { /* fping, reports ".... alive (0.43 ms)" */ seconds = atof(p+7); tmod = p + 7; tmod += strspn(tmod, "0123456789. "); } if (strncmp(tmod, "ms", 2) == 0) seconds = seconds / 1000.0; else if (strncmp(tmod, "usec", 4) == 0) seconds = seconds / 1000000.0; setupfn("tcp.%s.rrd", testname); sprintf(rrdvalues, "%d:%.6f", (int)tstamp, seconds); return create_and_update_rrd(hostname, rrdfn, bbnet_params, bbnet_tpl); } else { /* * Normal network tests - pick up the "Seconds:" value */ p = strstr(msg, "\nSeconds:"); if (p && (sscanf(p+1, "Seconds: %f", &seconds) == 1)) { setupfn("tcp.%s.rrd", testname); sprintf(rrdvalues, "%d:%.2f", (int)tstamp, seconds); return create_and_update_rrd(hostname, rrdfn, bbnet_params, bbnet_tpl); } } return 0; }
int do_mailq_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *mailq_params[] = { "DS:mailq:GAUGE:600:0:U", NULL }; static void *mailq_tpl = NULL; char *p; char *inqueue, *outqueue; int mailq, inq, outq; if (mailq_tpl == NULL) mailq_tpl = setup_template(mailq_params); /* * The normail "mailq" report only has a "... N requests" line and a single graph. * Erik's enhanced script has both an incoming and an outgoing mail queue, with * two different RRD's. We'll try to handle both setups. */ outqueue = strstr(msg, "\nMail queue out:"); inqueue = strstr(msg, "\nMail queue in:"); if (inqueue && outqueue) { /* Dual queue message */ /* Skip the "Mail queue X" line */ outqueue = strchr(outqueue+1, '\n'); inqueue = strchr(inqueue+1, '\n'); if ((outqueue == NULL) || (inqueue == NULL)) return 0; outqueue++; inqueue++; /* Next line has "&green Mail Queue (26 requests)". Cut string at end-of-line */ p = strchr(outqueue, '\n'); if (p) *p = '\0'; p = strchr(inqueue, '\n'); if (p) *p = '\0'; /* Skip until we find a number, and get the digit. */ p = outqueue + strcspn(outqueue, "0123456789"); outq = atoi(p); p = inqueue + strcspn(inqueue, "0123456789"); inq = atoi(p); /* Update RRD's */ setupfn("%s.rrd", "mailqin"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, inq); create_and_update_rrd(hostname, testname, classname, pagepaths, mailq_params, mailq_tpl); setupfn("%s.rrd", "mailqout"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, outq); create_and_update_rrd(hostname, testname, classname, pagepaths, mailq_params, mailq_tpl); return 0; } else { char *valptr; /* Looking for "... N requests ... " */ valptr = strstr(msg, "requests"); if (valptr) { /* Go back past any whitespace before "requests" */ do { valptr--; } while ((valptr > msg) && (*valptr != '\n') && isspace((int)*valptr)); /* Go back to the beginning of the number */ while ((valptr > msg) && isdigit((int) *(valptr-1))) valptr--; mailq = atoi(valptr); setupfn("%s.rrd", "mailq"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, mailq); return create_and_update_rrd(hostname, testname, classname, pagepaths, mailq_params, mailq_tpl); } } return 0; }
int do_ifstat_rrd(char *hostname, char *testname, char *msg, time_t tstamp) { static int pcres_compiled = 0; static pcre **ifstat_linux_pcres = NULL; static pcre **ifstat_freebsd_pcres = NULL; static pcre **ifstat_openbsd_pcres = NULL; static pcre **ifstat_netbsd_pcres = NULL; static pcre **ifstat_darwin_pcres = NULL; static pcre **ifstat_solaris_pcres = NULL; static pcre **ifstat_aix_pcres = NULL; static pcre **ifstat_hpux_pcres = NULL; static pcre **ifstat_sco_sv_pcres = NULL; static pcre **ifstat_bbwin_pcres = NULL; enum ostype_t ostype; char *datapart = msg; char *outp; char *bol, *eoln, *ifname, *rxstr, *txstr, *dummy; int dmatch; if (pcres_compiled == 0) { pcres_compiled = 1; ifstat_linux_pcres = compile_exprs("LINUX", ifstat_linux_exprs, (sizeof(ifstat_linux_exprs) / sizeof(ifstat_linux_exprs[0]))); ifstat_freebsd_pcres = compile_exprs("FREEBSD", ifstat_freebsd_exprs, (sizeof(ifstat_freebsd_exprs) / sizeof(ifstat_freebsd_exprs[0]))); ifstat_openbsd_pcres = compile_exprs("OPENBSD", ifstat_openbsd_exprs, (sizeof(ifstat_openbsd_exprs) / sizeof(ifstat_openbsd_exprs[0]))); ifstat_netbsd_pcres = compile_exprs("NETBSD", ifstat_netbsd_exprs, (sizeof(ifstat_netbsd_exprs) / sizeof(ifstat_netbsd_exprs[0]))); ifstat_darwin_pcres = compile_exprs("DARWIN", ifstat_darwin_exprs, (sizeof(ifstat_darwin_exprs) / sizeof(ifstat_darwin_exprs[0]))); ifstat_solaris_pcres = compile_exprs("SOLARIS", ifstat_solaris_exprs, (sizeof(ifstat_solaris_exprs) / sizeof(ifstat_solaris_exprs[0]))); ifstat_aix_pcres = compile_exprs("AIX", ifstat_aix_exprs, (sizeof(ifstat_aix_exprs) / sizeof(ifstat_aix_exprs[0]))); ifstat_hpux_pcres = compile_exprs("HPUX", ifstat_hpux_exprs, (sizeof(ifstat_hpux_exprs) / sizeof(ifstat_hpux_exprs[0]))); ifstat_sco_sv_pcres = compile_exprs("SCO_SV", ifstat_sco_sv_exprs, (sizeof(ifstat_sco_sv_exprs) / sizeof(ifstat_sco_sv_exprs[0]))); ifstat_bbwin_pcres = compile_exprs("BBWIN", ifstat_bbwin_exprs, (sizeof(ifstat_bbwin_exprs) / sizeof(ifstat_bbwin_exprs[0]))); } if (ifstat_tpl == NULL) ifstat_tpl = setup_template(ifstat_params); if ((strncmp(msg, "status", 6) == 0) || (strncmp(msg, "data", 4) == 0)) { /* Skip the first line of full status- and data-messages. */ datapart = strchr(msg, '\n'); if (datapart) datapart++; else datapart = msg; } ostype = get_ostype(datapart); datapart = strchr(datapart, '\n'); if (datapart) { datapart++; } else { errprintf("Too few lines in ifstat report from %s\n", hostname); return -1; } /* Setup the update string */ outp = rrdvalues + sprintf(rrdvalues, "%d", (int)tstamp); dmatch = 0; ifname = rxstr = txstr = dummy = NULL; bol = datapart; while (bol) { eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; switch (ostype) { case OS_LINUX22: case OS_LINUX: case OS_RHEL3: if (pickdata(bol, ifstat_linux_pcres[0], 1, &ifname)) { /* * Linux' netif aliases mess up things. * Clear everything when we see an interface name. * But we dont want to track the "lo" interface. */ if (strcmp(ifname, "lo") == 0) { xfree(ifname); ifname = NULL; } else { dmatch = 1; if (rxstr) { xfree(rxstr); rxstr = NULL; } if (txstr) { xfree(txstr); txstr = NULL; } } } else if (pickdata(bol, ifstat_linux_pcres[1], 1, &rxstr, &txstr)) dmatch |= 6; break; case OS_FREEBSD: if (pickdata(bol, ifstat_freebsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; case OS_OPENBSD: if (pickdata(bol, ifstat_openbsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; case OS_NETBSD: if (pickdata(bol, ifstat_netbsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; case OS_SOLARIS: if (pickdata(bol, ifstat_solaris_pcres[0], 0, &ifname, &txstr)) dmatch |= 1; else if (pickdata(bol, ifstat_solaris_pcres[1], 0, &dummy, &rxstr)) dmatch |= 6; if (ifname && dummy && (strcmp(ifname, dummy) != 0)) { /* They must match, drop the data */ errprintf("Host %s has weird ifstat data - device name mismatch %s:%s\n", hostname, ifname, dummy); xfree(ifname); xfree(txstr); xfree(rxstr); xfree(dummy); dmatch = 0; } break; case OS_AIX: if (pickdata(bol, ifstat_aix_pcres[0], 1, &ifname)) { /* Interface names comes first, so any rx/tx data is discarded */ dmatch |= 1; if (rxstr) { xfree(rxstr); rxstr = NULL; } if (txstr) { xfree(txstr); txstr = NULL; } } else if (pickdata(bol, ifstat_aix_pcres[1], 1, &txstr, &rxstr)) dmatch |= 6; break; case OS_HPUX: if (pickdata(bol, ifstat_hpux_pcres[0], 1, &ifname)) { /* Interface names comes first, so any rx/tx data is discarded */ dmatch |= 1; if (rxstr) { xfree(rxstr); rxstr = NULL; } if (txstr) { xfree(txstr); txstr = NULL; } } else if (pickdata(bol, ifstat_hpux_pcres[1], 1, &rxstr)) dmatch |= 2; else if (pickdata(bol, ifstat_hpux_pcres[2], 1, &txstr)) dmatch |= 4; break; case OS_DARWIN: if (pickdata(bol, ifstat_darwin_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; case OS_SCO_SV: if (pickdata(bol, ifstat_sco_sv_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; case OS_WIN32_BBWIN: if (pickdata(bol, ifstat_bbwin_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7; break; case OS_OSF: case OS_IRIX: case OS_SNMP: case OS_WIN32: case OS_UNKNOWN: break; } if ((dmatch == 7) && ifname && rxstr && txstr) { setupfn("ifstat.%s.rrd", ifname); sprintf(rrdvalues, "%d:%s:%s", (int)tstamp, txstr, rxstr); create_and_update_rrd(hostname, rrdfn, ifstat_params, ifstat_tpl); xfree(ifname); xfree(rxstr); xfree(txstr); if (dummy) xfree(dummy); ifname = rxstr = txstr = dummy = NULL; dmatch = 0; } if (eoln) { *eoln = '\n'; bol = eoln+1; if (*bol == '\0') bol = NULL; } else { bol = NULL; } } if (ifname) xfree(ifname); if (rxstr) xfree(rxstr); if (txstr) xfree(txstr); if (dummy) xfree(dummy); return 0; }
int do_xymongen_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *xymon_params[] = { "DS:runtime:GAUGE:600:0:U", NULL }; static void *xymon_tpl = NULL; static char *xymon2_params[] = { "DS:hostcount:GAUGE:600:0:U", "DS:statuscount:GAUGE:600:0:U", NULL }; static void *xymon2_tpl = NULL; static char *xymon3_params[] = { "DS:redcount:GAUGE:600:0:U", "DS:rednopropcount:GAUGE:600:0:U", "DS:yellowcount:GAUGE:600:0:U", "DS:yellownopropcount:GAUGE:600:0:U", "DS:greencount:GAUGE:600:0:U", "DS:purplecount:GAUGE:600:0:U", "DS:clearcount:GAUGE:600:0:U", "DS:bluecount:GAUGE:600:0:U", "DS:redpct:GAUGE:600:0:100", "DS:rednoproppct:GAUGE:600:0:100", "DS:yellowpct:GAUGE:600:0:100", "DS:yellownoproppct:GAUGE:600:0:100", "DS:greenpct:GAUGE:600:0:100", "DS:purplepct:GAUGE:600:0:100", "DS:clearpct:GAUGE:600:0:100", "DS:bluepct:GAUGE:600:0:100", NULL }; static void *xymon3_tpl = NULL; char *p, *bol, *eoln; float runtime; int hostcount, statuscount; int redcount, rednopropcount, yellowcount, yellownopropcount, greencount, purplecount, clearcount, bluecount; double pctredcount, pctrednopropcount, pctyellowcount, pctyellownopropcount, pctgreencount, pctpurplecount, pctclearcount, pctbluecount; if (xymon_tpl == NULL) xymon_tpl = setup_template(xymon_params); if (xymon2_tpl == NULL) xymon2_tpl = setup_template(xymon2_params); if (xymon3_tpl == NULL) xymon3_tpl = setup_template(xymon3_params); runtime = 0.0; hostcount = statuscount = 0; redcount = rednopropcount = yellowcount = yellownopropcount = 0; greencount = purplecount = clearcount = bluecount = 0; pctredcount = pctrednopropcount = pctyellowcount = pctyellownopropcount = 0.0; pctgreencount = pctpurplecount = pctclearcount = pctbluecount = 0.0; bol = msg; do { int *valptr = NULL; double *pctvalptr = NULL; eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; p = bol + strspn(bol, " \t"); if (strncmp(p, "TIME TOTAL", 10) == 0) sscanf(p, "TIME TOTAL %f", &runtime); else if (strncmp(p, "Hosts", 5) == 0) valptr = &hostcount; else if (strncmp(p, "Status messages", 15) == 0) valptr = &statuscount; else if (strncmp(p, "- Red (non-propagating)", 23) == 0) { valptr = &rednopropcount; pctvalptr = &pctrednopropcount; } else if (strncmp(p, "- Red", 5) == 0) { valptr = &redcount; pctvalptr = &pctredcount; } else if (strncmp(p, "- Yellow (non-propagating)", 26) == 0) { valptr = &yellownopropcount; pctvalptr = &pctyellownopropcount; } else if (strncmp(p, "- Yellow", 8) == 0) { valptr = &yellowcount; pctvalptr = &pctyellowcount; } else if (strncmp(p, "- Green", 7) == 0) { valptr = &greencount; pctvalptr = &pctgreencount; } else if (strncmp(p, "- Purple", 8) == 0) { valptr = &purplecount; pctvalptr = &pctpurplecount; } else if (strncmp(p, "- Clear", 7) == 0) { valptr = &clearcount; pctvalptr = &pctclearcount; } else if (strncmp(p, "- Blue", 6) == 0) { valptr = &bluecount; pctvalptr = &pctbluecount; } if (valptr) { p = strchr(bol, ':'); if (p) { *valptr = atoi(p+1); if (pctvalptr) { p = strchr(p, '('); if (p) *pctvalptr = atof(p+1); } } } bol = (eoln ? eoln+1 : NULL); } while (bol); if (strcmp("xymongen", testname) != 0) { setupfn2("%s.%s.rrd", "xymongen", testname); } else { setupfn("%s.rrd", "xymongen"); } snprintf(rrdvalues, sizeof(rrdvalues), "%d:%.2f", (int)tstamp, runtime); create_and_update_rrd(hostname, testname, classname, pagepaths, xymon_params, xymon_tpl); if (strcmp("xymongen", testname) != 0) { setupfn2("%s.%s.rrd", "xymon", testname); } else { setupfn("%s.rrd", "xymon"); } snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d:%d", (int)tstamp, hostcount, statuscount); create_and_update_rrd(hostname, testname, classname, pagepaths, xymon2_params, xymon2_tpl); if (strcmp("xymongen", testname) != 0) { setupfn2("%s.%s.rrd", "xymon2", testname); } else { setupfn("%s.rrd", "xymon2"); } snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d:%d:%d:%d:%d:%d:%d:%d:%5.2f:%5.2f:%5.2f:%5.2f:%5.2f:%5.2f:%5.2f:%5.2f", (int)tstamp, redcount, rednopropcount, yellowcount, yellownopropcount, greencount, purplecount, clearcount, bluecount, pctredcount, pctrednopropcount, pctyellowcount, pctyellownopropcount, pctgreencount, pctpurplecount, pctclearcount, pctbluecount); create_and_update_rrd(hostname, testname, classname, pagepaths, xymon3_params, xymon3_tpl); return 0; }
int do_vmstat_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { enum ostype_t ostype; vmstat_layout_t *layout = NULL; char *datapart = msg; int values[MAX_VMSTAT_VALUES]; int defcount, defidx, datacount, result; char *p; char **creparams; if ((strncmp(msg, "status", 6) == 0) || (strncmp(msg, "data", 4) == 0)) { /* Full message, including "status" or "data" line - so skip the first line. */ datapart = strchr(msg, '\n'); if (datapart) { datapart++; } else { errprintf("Too few lines (only 1) in vmstat report from %s\n", hostname); return -1; } } ostype = get_ostype(datapart); datapart = strchr(datapart, '\n'); if (datapart) { datapart++; } else { errprintf("Too few lines (only 1 or 2) in vmstat report from %s\n", hostname); return -1; } /* Pick up the values in the datapart line. Stop at newline. */ p = strchr(datapart, '\n'); if (p) *p = '\0'; p = strtok(datapart, " "); datacount = 0; while (p && (datacount < MAX_VMSTAT_VALUES)) { values[datacount++] = atoi(p); p = strtok(NULL, " "); } /* Must do this now, to check on the layout of any existing file */ setupfn("%s.rrd", "vmstat"); switch (ostype) { case OS_SOLARIS: layout = vmstat_solaris_layout; break; case OS_OSF: layout = vmstat_osf_layout; break; case OS_AIX: /* Special, because there are two layouts for AIX */ { char **dsnames = NULL; int dscount, i; dscount = rrddatasets(hostname, &dsnames); layout = ((dscount == 17) ? vmstat_aix_layout : vmstat_aix_power5_layout); if ((dscount > 0) && dsnames) { /* Free the dsnames list */ for (i=0; (i<dscount); i++) xfree(dsnames[i]); xfree(dsnames); } } break; case OS_IRIX: layout = vmstat_irix_layout; break; case OS_HPUX: layout = vmstat_hpux_layout; break; case OS_FREEBSD: layout = vmstat_freebsd_layout; break; case OS_NETBSD: layout = vmstat_netbsd_layout; break; case OS_OPENBSD: layout = vmstat_openbsd_layout; break; case OS_LINUX22: layout = vmstat_linux22_layout; break; case OS_LINUX: case OS_ZVM: case OS_ZVSE: case OS_ZOS: layout = vmstat_linux_layout; break; case OS_RHEL3: layout = vmstat_rhel3_layout; break; case OS_SCO_SV: layout = vmstat_sco_sv_layout; break; case OS_UNKNOWN: errprintf("Host '%s' reports vmstat for an unknown OS\n", hostname); return -1; default: errprintf("Cannot handle vmstat from host '%s' \n", hostname); return -1; } if (layout == NULL) { return -1; } /* How many values are defined in the dataset ? */ for (defcount = 0; (layout[defcount].name); defcount++) ; /* Setup the create-parameters */ creparams = (char **)malloc((defcount+1)*sizeof(char *)); for (defidx=0; (defidx < defcount); defidx++) { creparams[defidx] = (char *)malloc(strlen(layout[defidx].name) + strlen("DS::GAUGE:600:0:U") + 1); sprintf(creparams[defidx], "DS:%s:GAUGE:600:0:U", layout[defidx].name); } creparams[defcount] = NULL; /* Setup the update string, picking out values according to the layout */ p = rrdvalues + snprintf(rrdvalues, sizeof(rrdvalues), "%d", (int)tstamp); for (defidx=0; (defidx < defcount); defidx++) { int dataidx = layout[defidx].index; if ((dataidx >= datacount) || (dataidx == -1)) { p += snprintf(p, sizeof(rrdvalues)-(p-rrdvalues), ":U"); } else { p += snprintf(p, sizeof(rrdvalues)-(p-rrdvalues), ":%d", values[layout[defidx].index]); } } result = create_and_update_rrd(hostname, testname, classname, pagepaths, creparams, NULL); for (defidx=0; (defidx < defcount); defidx++) xfree(creparams[defidx]); xfree(creparams); return result; }
int do_xymond_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *xymond_params[] = { "DS:inmessages:DERIVE:600:0:U", "DS:statusmessages:DERIVE:600:0:U", "DS:combomessages:DERIVE:600:0:U", "DS:pagemessages:DERIVE:600:0:U", "DS:summarymessages:DERIVE:600:0:U", "DS:datamessages:DERIVE:600:0:U", "DS:notesmessages:DERIVE:600:0:U", "DS:enablemessages:DERIVE:600:0:U", "DS:disablemessages:DERIVE:600:0:U", "DS:ackmessages:DERIVE:600:0:U", "DS:configmessages:DERIVE:600:0:U", "DS:querymessages:DERIVE:600:0:U", "DS:boardmessages:DERIVE:600:0:U", "DS:listmessages:DERIVE:600:0:U", "DS:logmessages:DERIVE:600:0:U", "DS:dropmessages:DERIVE:600:0:U", "DS:renamemessages:DERIVE:600:0:U", "DS:statuschmsgs:DERIVE:600:0:U", "DS:stachgchmsgs:DERIVE:600:0:U", "DS:pagechmsgs:DERIVE:600:0:U", "DS:datachmsgs:DERIVE:600:0:U", "DS:noteschmsgs:DERIVE:600:0:U", "DS:enadischmsgs:DERIVE:600:0:U", NULL }; static void *xymond_tpl = NULL; struct { char *marker; unsigned long val; } xymond_data[] = { { "\nIncoming messages", 0 }, { "\n- status", 0 }, { "\n- combo", 0 }, { "\n- page", 0 }, { "\n- summary", 0 }, { "\n- data", 0 }, { "\n- notes", 0 }, { "\n- enable", 0 }, { "\n- disable", 0 }, { "\n- ack", 0 }, { "\n- config", 0 }, { "\n- query", 0 }, { "\n- xymondboard", 0 }, { "\n- xymondlist", 0 }, { "\n- xymondlog", 0 }, { "\n- drop", 0 }, { "\n- rename", 0 }, { "\nstatus channel messages", 0 }, { "\nstachg channel messages", 0 }, { "\npage channel messages", 0 }, { "\ndata channel messages", 0 }, { "\nnotes channel messages", 0 }, { "\nenadis channel messages", 0 }, { NULL, 0 } }; int i, gotany = 0; char *p; char valstr[10]; MEMDEFINE(valstr); if (xymond_tpl == NULL) xymond_tpl = setup_template(xymond_params); sprintf(rrdvalues, "%d", (int)tstamp); i = 0; while (xymond_data[i].marker) { p = strstr(msg, xymond_data[i].marker); if (p) { if (*p == '\n') p++; p += strcspn(p, ":\r\n"); if (*p == ':') { xymond_data[i].val = atol(p+1); gotany++; sprintf(valstr, ":%lu", xymond_data[i].val); strcat(rrdvalues, valstr); } else strcat(rrdvalues, ":U"); } else strcat(rrdvalues, ":U"); i++; } if (gotany) { if (strcmp("xymond", testname) != 0) { setupfn2("%s.%s.rrd", "xymond", testname); } else { setupfn("%s.rrd", "xymond"); } MEMUNDEFINE(valstr); return create_and_update_rrd(hostname, testname, classname, pagepaths, xymond_params, xymond_tpl); } MEMUNDEFINE(valstr); return 0; }