示例#1
0
void do_eventlog(FILE *output, int maxcount, int maxminutes, char *fromtime, char *totime, 
		char *pageregex, char *expageregex,
		char *hostregex, char *exhostregex,
		char *testregex, char *extestregex,
		char *colrregex, int ignoredialups,
		f_hostcheck hostcheck,
		event_t **eventlist, countlist_t **hostcounts, countlist_t **servicecounts,
		countsummary_t counttype, eventsummary_t sumtype, char *periodstring)
{
	FILE *eventlog;
	char eventlogfilename[PATH_MAX];
	time_t firstevent = 0;
	time_t lastevent = getcurrenttime(NULL);
	event_t	*eventhead = NULL;
	struct stat st;
	char l[MAX_LINE_LEN];
	char title[200];

	/* For the PCRE matching */
	const char *errmsg = NULL;
	int errofs = 0;
	pcre *pageregexp = NULL;
	pcre *expageregexp = NULL;
	pcre *hostregexp = NULL;
	pcre *exhostregexp = NULL;
	pcre *testregexp = NULL;
	pcre *extestregexp = NULL;
	pcre *colrregexp = NULL;
	countlist_t *hostcounthead = NULL, *svccounthead = NULL;

	if (eventlist) *eventlist = NULL;
	if (hostcounts) *hostcounts = NULL;
	if (servicecounts) *servicecounts = NULL;

	havedoneeventlog = 1;

	if ((maxminutes > 0) && (fromtime || totime)) {
		fprintf(output, "<B>Only one time interval type is allowed!</B>");
		return;
	}

	if (fromtime) {
		firstevent = eventreport_time(fromtime);
		if(firstevent < 0) {
			if (output) fprintf(output,"<B>Invalid 'from' time: %s</B>", htmlquoted(fromtime));
			return;
		}
	}
	else if (maxminutes == -1) {
		/* Unlimited number of minutes */
		firstevent = 0;
	}
	else if (maxminutes > 0) {
		firstevent = getcurrenttime(NULL) - maxminutes*60;
	}
	else {
		firstevent = getcurrenttime(NULL) - 86400;
	}

	if (totime) {
		lastevent = eventreport_time(totime);
		if (lastevent < 0) {
			if (output) fprintf(output,"<B>Invalid 'to' time: %s</B>", htmlquoted(totime));
			return;
		}
		if (lastevent < firstevent) {
			if (output) fprintf(output,"<B>'to' time must be after 'from' time.</B>");
			return;
		}
	}

	if (!maxcount) maxcount = 100;

	if (pageregex && *pageregex) pageregexp = pcre_compile(pageregex, PCRE_CASELESS, &errmsg, &errofs, NULL);
	if (expageregex && *expageregex) expageregexp = pcre_compile(expageregex, PCRE_CASELESS, &errmsg, &errofs, NULL);
	if (hostregex && *hostregex) hostregexp = pcre_compile(hostregex, PCRE_CASELESS, &errmsg, &errofs, NULL);
	if (exhostregex && *exhostregex) exhostregexp = pcre_compile(exhostregex, PCRE_CASELESS, &errmsg, &errofs, NULL);
	if (testregex && *testregex) testregexp = pcre_compile(testregex, PCRE_CASELESS, &errmsg, &errofs, NULL);
	if (extestregex && *extestregex) extestregexp = pcre_compile(extestregex, PCRE_CASELESS, &errmsg, &errofs, NULL);
	if (colrregex && *colrregex) colrregexp = pcre_compile(colrregex, PCRE_CASELESS, &errmsg, &errofs, NULL);

	sprintf(eventlogfilename, "%s/allevents", xgetenv("XYMONHISTDIR"));
	eventlog = fopen(eventlogfilename, "r");

	if (eventlog && (stat(eventlogfilename, &st) == 0)) {
		time_t curtime;
		int done = 0;
		int unlimited = (maxcount == -1);

		if (unlimited) maxcount = 1000;
		do {
			/* Find a spot in the eventlog file close to where the firstevent time is */
			fseeko(eventlog, 0, SEEK_END);
			do {
				/* Go back maxcount*80 bytes - one entry is ~80 bytes */
				if (ftello(eventlog) > maxcount*80) {
					unsigned int uicurtime;
					fseeko(eventlog, -maxcount*80, SEEK_CUR); 
					if (fgets(l, sizeof(l), eventlog) &&  /* Skip to start of line */
					    fgets(l, sizeof(l), eventlog)) {
						sscanf(l, "%*s %*s %u %*u %*u %*s %*s %*d", &uicurtime);
						curtime = uicurtime;
						done = (curtime < firstevent);
						if (unlimited && !done) maxcount += 1000;
					}
					else {
						if (output) fprintf(output,"Error reading eventlog file %s: %s\n", eventlogfilename, strerror(errno));
						return;
					}
				}
				else {
					rewind(eventlog);
					curtime = 0;
					done = 1;
				}
			} while (!done);

			if (unlimited) unlimited = ((curtime > firstevent) && (ftello(eventlog) > 0));
		} while (unlimited);
	}
	
	eventhead = NULL;

	while (eventlog && (fgets(l, sizeof(l), eventlog))) {

		time_t eventtime, changetime, duration;
		unsigned int uievt, uicht, uidur;
		char hostname[MAX_LINE_LEN], svcname[MAX_LINE_LEN], newcol[MAX_LINE_LEN], oldcol[MAX_LINE_LEN];
		char *newcolname, *oldcolname;
		int state, itemsfound, colrmatch;
		event_t *newevent;
		void *eventhost;
		struct htnames_t *eventcolumn;
		int ovector[30];
		eventcount_t *countrec;

		itemsfound = sscanf(l, "%s %s %u %u %u %s %s %d",
			hostname, svcname,
			&uievt, &uicht, &uidur, 
			newcol, oldcol, &state);
		eventtime = uievt; changetime = uicht; duration = uidur;
		oldcolname = colorname(eventcolor(oldcol));
		newcolname = colorname(eventcolor(newcol));
		/* For DURATION counts, we must parse all events until now */
		if ((counttype != XYMON_COUNT_DURATION) && (eventtime > lastevent)) break;
		eventhost = hostinfo(hostname);
		eventcolumn = getname(svcname, 1);

		if ( (itemsfound == 8) && 
		     (eventtime >= firstevent) && 
		     (eventhost && !xmh_item(eventhost, XMH_FLAG_NONONGREEN)) && 
		     (wanted_eventcolumn(svcname)) ) {

			if (eventfilter(eventhost, svcname, 
					pageregexp, expageregexp, 
					hostregexp, exhostregexp,
					testregexp, extestregexp,
					ignoredialups, hostcheck) == 0) continue;

			/* For duration counts, record all events. We'll filter out the colors later. */
			if (colrregexp && (counttype != XYMON_COUNT_DURATION)) {
				colrmatch = ( (pcre_exec(colrregexp, NULL, newcolname, strlen(newcolname), 0, 0,
							ovector, (sizeof(ovector)/sizeof(int))) >= 0) ||
					      (pcre_exec(colrregexp, NULL, oldcolname, strlen(oldcolname), 0, 0,
							ovector, (sizeof(ovector)/sizeof(int))) >= 0) );
			}
			else
				colrmatch = 1;
			if (!colrmatch) continue;

			newevent = (event_t *) malloc(sizeof(event_t));
			newevent->host       = eventhost;
			newevent->service    = eventcolumn;
			newevent->eventtime  = eventtime;
			newevent->changetime = changetime;
			newevent->duration   = duration;
			newevent->newcolor   = eventcolor(newcol);
			newevent->oldcolor   = eventcolor(oldcol);
			newevent->next = eventhead;
			eventhead = newevent;

			if (counttype != XYMON_COUNT_DURATION) {
				countrec = (eventcount_t *)xmh_item(eventhost, XMH_DATA);
				while (countrec && (countrec->service != eventcolumn)) countrec = countrec->next;
				if (countrec == NULL) {
					countrec = (eventcount_t *)calloc(1, sizeof(eventcount_t));
					countrec->service = eventcolumn;
					countrec->next = (eventcount_t *)xmh_item(eventhost, XMH_DATA);
					xmh_set_item(eventhost, XMH_DATA, (void *)countrec);
				}
				countrec->count++;
			}
		}
	}

	/* Count the state changes per host */
	svccounthead = hostcounthead = NULL;
	switch (counttype) {
	  case XYMON_COUNT_EVENTS: count_events(&hostcounthead, &svccounthead); break;
	  case XYMON_COUNT_DURATION: count_duration(firstevent, lastevent,
					       pageregexp, expageregexp,
					       hostregexp, exhostregexp,
					       testregexp, extestregexp,
					       ignoredialups, hostcheck,
					       eventhead, &hostcounthead, &svccounthead); break;
	  default: break;
	}

	if (hostcounthead) hostcounthead = msort(hostcounthead, record_compare, record_getnext, record_setnext);
	if (svccounthead)  svccounthead = msort(svccounthead, record_compare, record_getnext, record_setnext);

	if (eventhead && (output != NULL)) {
		char *bgcolors[2] = { "#000000", "#000033" };
		int  bgcolor = 0;
		struct event_t *ewalk, *lasttoshow = eventhead;
		countlist_t *cwalk;
		unsigned long totalcount = 0;

		if (periodstring) fprintf(output, "<p><font size=+1>%s</font></p>\n", htmlquoted(periodstring));

		switch (sumtype) {
		  case XYMON_S_HOST_BREAKDOWN:
			/* Request for a specific service, show breakdown by host */
			for (cwalk = hostcounthead; (cwalk); cwalk = cwalk->next) totalcount += cwalk->total;
			fprintf(output, "<table summary=\"Breakdown by host\" border=0>\n");
			fprintf(output, "<tr><th align=left>Host</th><th colspan=2>%s</th></tr>\n",
				(counttype == XYMON_COUNT_EVENTS) ? "State changes" : "Seconds red/yellow");
			fprintf(output, "<tr><td colspan=3><hr width=\"100%%\"></td></tr>\n");
			for (cwalk = hostcounthead; (cwalk && (cwalk->total > 0)); cwalk = cwalk->next) {
				fprintf(output, "<tr><td align=left>%s</td><td align=right>%lu</td><td align=right>(%6.2f %%)</tr>\n",
					xmh_item(cwalk->src, XMH_HOSTNAME), 
					cwalk->total, ((100.0 * cwalk->total) / totalcount));
			}
			fprintf(output, "</table>\n");
			break;

		  case XYMON_S_SERVICE_BREAKDOWN:
			/* Request for a specific host, show breakdown by service */
			for (cwalk = svccounthead; (cwalk); cwalk = cwalk->next) totalcount += cwalk->total;
			fprintf(output, "<table summary=\"Breakdown by service\" border=0>\n");
			fprintf(output, "<tr><th align=left>Service</th><th colspan=2>%s</th></tr>\n",
				(counttype == XYMON_COUNT_EVENTS) ? "State changes" : "Seconds red/yellow");
			fprintf(output, "<tr><td colspan=3><hr width=\"100%%\"></td></tr>\n");
			for (cwalk = svccounthead; (cwalk && (cwalk->total > 0)); cwalk = cwalk->next) {
				fprintf(output, "<tr><td align=left>%s</td><td align=right>%lu</td><td align=right>(%6.2f %%)</tr>\n",
					((htnames_t *)cwalk->src)->name, 
					cwalk->total, ((100.0 * cwalk->total) / totalcount));
			}
			fprintf(output, "</table>\n");
			break;

		  case XYMON_S_NONE:
			break;
		}

		if (sumtype == XYMON_S_NONE) {
			int  count;
			count=0;
			ewalk=eventhead; 
			do {
				count++;
				lasttoshow = ewalk;
				ewalk = ewalk->next;
			} while (ewalk && (count<maxcount));
			if (ewalk) ewalk->next = NULL;	/* Terminate list if any items left */

			if (maxminutes > 0)  { 
				sprintf(title, "%d events received in the past %u minutes", 
					count, (unsigned int)((getcurrenttime(NULL) - lasttoshow->eventtime) / 60));
			}
			else {
				sprintf(title, "%d events received.", count);
			}
		}
		else {
			strcpy(title, "Events in summary");
		}

		fprintf(output, "<BR><BR>\n");
		fprintf(output, "<TABLE SUMMARY=\"$EVENTSTITLE\" BORDER=0>\n");
		fprintf(output, "<TR BGCOLOR=\"#333333\">\n");
		fprintf(output, "<TD ALIGN=CENTER COLSPAN=6><FONT SIZE=-1 COLOR=\"#33ebf4\">%s</FONT></TD></TR>\n", htmlquoted(title));

		for (ewalk=eventhead; (ewalk); ewalk=ewalk->next) {
			char *hostname = xmh_item(ewalk->host, XMH_HOSTNAME);

			if ( (counttype == XYMON_COUNT_DURATION) &&
			     (ewalk->oldcolor < COL_YELLOW) &&
			     (ewalk->newcolor < COL_YELLOW) ) continue;

			if ( (counttype == XYMON_COUNT_DURATION) &&
			     (ewalk->eventtime >= lastevent) ) continue;

			fprintf(output, "<TR BGCOLOR=%s>\n", bgcolors[bgcolor]);
			bgcolor = ((bgcolor + 1) % 2);

			fprintf(output, "<TD ALIGN=CENTER>%s</TD>\n", ctime(&ewalk->eventtime));

			if (ewalk->newcolor == COL_CLEAR) {
				fprintf(output, "<TD ALIGN=CENTER BGCOLOR=black><FONT COLOR=white>%s</FONT></TD>\n",
					hostname);
			}
			else {
				fprintf(output, "<TD ALIGN=CENTER BGCOLOR=%s><FONT COLOR=black>%s</FONT></TD>\n",
					colorname(ewalk->newcolor), hostname);
			}

			fprintf(output, "<TD ALIGN=LEFT>%s</TD>\n", ewalk->service->name);
			fprintf(output, "<TD><A HREF=\"%s\">\n", 
				histlogurl(hostname, ewalk->service->name, ewalk->changetime, NULL));
			fprintf(output, "<IMG SRC=\"%s/%s\"  HEIGHT=\"%s\" WIDTH=\"%s\" BORDER=0 ALT=\"%s\" TITLE=\"%s\"></A>\n", 
				xgetenv("XYMONSKIN"), dotgiffilename(ewalk->oldcolor, 0, 0), 
				xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH"), 
				colorname(ewalk->oldcolor), colorname(ewalk->oldcolor));
			fprintf(output, "<IMG SRC=\"%s/arrow.gif\" BORDER=0 ALT=\"From -&gt; To\">\n", 
				xgetenv("XYMONSKIN"));
			fprintf(output, "<TD><A HREF=\"%s\">\n", 
				histlogurl(hostname, ewalk->service->name, ewalk->eventtime, NULL));
			fprintf(output, "<IMG SRC=\"%s/%s\"  HEIGHT=\"%s\" WIDTH=\"%s\" BORDER=0 ALT=\"%s\" TITLE=\"%s\"></A></TD>\n", 
				xgetenv("XYMONSKIN"), dotgiffilename(ewalk->newcolor, 0, 0), 
				xgetenv("DOTHEIGHT"), xgetenv("DOTWIDTH"), 
				colorname(ewalk->newcolor), colorname(ewalk->newcolor));
			fprintf(output, "</TR>\n");
		}

		fprintf(output, "</TABLE>\n");

	}
	else if (output != NULL) {
		/* No events during the past maxminutes */
		if (eventlog)
			sprintf(title, "No events received in the last %d minutes", maxminutes);
		else
			strcpy(title, "No events logged");

		fprintf(output, "<CENTER><BR>\n");
		fprintf(output, "<TABLE SUMMARY=\"%s\" BORDER=0>\n", title);
		fprintf(output, "<TR BGCOLOR=\"#333333\">\n");
		fprintf(output, "<TD ALIGN=CENTER COLSPAN=6><FONT SIZE=-1 COLOR=\"#33ebf4\">%s</FONT></TD>\n", htmlquoted(title));
		fprintf(output, "</TR>\n");
		fprintf(output, "</TABLE>\n");
		fprintf(output, "</CENTER>\n");
	}

	if (eventlog) fclose(eventlog);

	if (pageregexp) pcre_free(pageregexp);
	if (hostregexp) pcre_free(hostregexp);
	if (testregexp) pcre_free(testregexp);
	if (colrregexp) pcre_free(colrregexp);

	/* Return the event- and count-lists, if wanted - or clean them up */
	if (eventlist) {
		*eventlist = eventhead;
	}
	else {
		event_t	*zombie, *ewalk = eventhead;
		while (ewalk) { zombie = ewalk; ewalk = ewalk->next; xfree(zombie); }
	}

	if (hostcounts) {
		*hostcounts = hostcounthead;
	}
	else {
		countlist_t *zombie, *hwalk = hostcounthead;
		while (hwalk) { zombie = hwalk; hwalk = hwalk->next; xfree(zombie); }

	}

	if (servicecounts) {
		*servicecounts = svccounthead;
	}
	else {
		countlist_t *zombie, *swalk = svccounthead;
		while (swalk) { zombie = swalk; swalk = swalk->next; xfree(zombie); }
	}
}
示例#2
0
int main(int argc, char *argv[])
{
	int argi;
	char *envarea = NULL;

	for (argi=1; (argi < argc); argi++) {
		if (argnmatch(argv[argi], "--env=")) {
			char *p = strchr(argv[argi], '=');
			loadenv(p+1, envarea);
		}
		else if (argnmatch(argv[argi], "--area=")) {
			char *p = strchr(argv[argi], '=');
			envarea = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--top")) {
			topcount = 10;
			webfile_hf = "topchanges";
			webfile_form = "topchanges_form";
			maxminutes = -1;
			maxcount = -1;
		}
		else if (strcmp(argv[argi], "--debug=")) {
			debug = 1;
		}
	}

	redirect_cgilog("eventlog");
	load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());

	fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));

	cgidata = cgi_request();
	if (cgidata == NULL) {
		/* Present the query form */
		sethostenv("", "", "", colorname(COL_BLUE), NULL);
		showform(stdout, webfile_hf, webfile_form, COL_BLUE, getcurrenttime(NULL), NULL, NULL);
		return 0;
	}

	*periodstring = '\0';
	parse_query();

	if ((*periodstring == '\0') && (fromtime || totime)) {
		if (fromtime && totime) sprintf(periodstring, "Events between %s - %s", fromtime, totime);
		else if (fromtime) sprintf(periodstring, "Events since %s", fromtime);
		else if (totime) sprintf(periodstring, "Events until %s", totime);
	}

	/* Now generate the webpage */
	headfoot(stdout, webfile_hf, "", "header", COL_GREEN);
	fprintf(stdout, "<center>\n");

	if (topcount == 0) {
		do_eventlog(stdout, maxcount, maxminutes, fromtime, totime, 
			    pageregex, expageregex, hostregex, exhostregex, testregex, extestregex,
			    colorregex, ignoredialups, NULL,
			    NULL, NULL, NULL, counttype, summarybar, periodstring);
	}
	else {
		countlist_t *hcounts, *scounts;
		event_t *events;
		time_t firstevent, lastevent;

		do_eventlog(NULL, -1, -1, fromtime, totime, 
			    pageregex, expageregex, hostregex, exhostregex, testregex, extestregex,
			    colorregex, ignoredialups, NULL,
			    &events, &hcounts, &scounts, counttype, XYMON_S_NONE, NULL);

		lastevent = (totime ? eventreport_time(totime) : getcurrenttime(NULL));

		if (fromtime) {
			firstevent = eventreport_time(fromtime);
		}
		else if (events) {
			event_t *ewalk;
			ewalk = events; while (ewalk->next) ewalk = ewalk->next;
			firstevent = ewalk->eventtime;
		}
		else
			firstevent = 0;

		show_topchanges(stdout, hcounts, scounts, events, topcount, firstevent, lastevent);
	}

	fprintf(stdout, "</center>\n");
	headfoot(stdout, webfile_hf, "", "footer", COL_GREEN);

	return 0;
}