Ejemplo n.º 1
0
state_t *init_state(char *filename, logdata_t *log)
{
	FILE 		*fd = NULL;
	char		*p;
	char		*hostname;
	char		*testname;
	char		*testnameidx;
	state_t 	*newstate;
	char		fullfn[PATH_MAX];
	host_t		*host;
	struct stat 	log_st;
	time_t		now = getcurrenttime(NULL);
	time_t		histentry_start;
	int		logexpired = 0;
	int		propagating, isacked;

	dbgprintf("init_state(%s, %d, ...)\n", textornull(filename));

	/* Ignore summary files and dot-files (this catches "." and ".." also) */
	if ( (strncmp(filename, "summary.", 8) == 0) || (filename[0] == '.')) {
		return NULL;
	}

	if (reportstart || snapshot) {
		/* Dont do reports for info- and trends-columns */
		p = strrchr(filename, '.');
		if (p == NULL) return NULL;
		p++;

		if (strcmp(p, xgetenv("INFOCOLUMN")) == 0) return NULL;
		if (strcmp(p, xgetenv("TRENDSCOLUMN")) == 0) return NULL;

		/*
		 * When doing reports, we are scanning the BBHIST directory. It may
		 * contain files that are named as a host only (no test-name).
		 * Skip those.
		 */
		if (find_host(filename)) return NULL;
	}

	if (!reportstart && !snapshot) {
		hostname = strdup(log->hostname);
		testname = strdup(log->testname);
		logexpired = (log->validtime < now);
	}
	else {
		sprintf(fullfn, "%s/%s", xgetenv("BBHIST"), filename);

		/* Check that we can access this file */
		if ( (stat(fullfn, &log_st) == -1)       || 
		     (!S_ISREG(log_st.st_mode))            ||
		     ((fd = fopen(fullfn, "r")) == NULL)   ) {
			errprintf("Weird file '%s' skipped\n", fullfn);
			return NULL;
		}

		/* Pick out host- and test-name */
		logexpired = (log_st.st_mtime < now);
		hostname = strdup(filename);
		p = strrchr(hostname, '.');

		/* Skip files that have no '.' in filename */
		if (p) {
			/* Pick out the testname ... */
			*p = '\0'; p++;
			testname = strdup(p);
	
			/* ... and change hostname back into normal form */
			for (p=hostname; (*p); p++) {
				if (*p == ',') *p='.';
			}
		}
		else {
			xfree(hostname);
			fclose(fd);
			return NULL;
		}
	}

	/* Must do these first to get the propagation value for the statistics */
	host = find_host(hostname);
	isacked = (log->acktime > now);
	propagating = checkpropagation(host, testname, log->color, isacked);

	/* Count all of the real columns */
	if ( (strcmp(testname, xgetenv("INFOCOLUMN")) != 0) && (strcmp(testname, xgetenv("TRENDSCOLUMN")) != 0) ) {
		statuscount++;
		switch (log->color) {
		  case COL_RED:
		  case COL_YELLOW:
			if (propagating) colorcount[log->color] += 1;
			else colorcount_noprop[log->color] += 1;
			break;

		  default:
			colorcount[log->color] += 1;
			break;
		}
	}

	testnameidx = (char *)malloc(strlen(testname) + 3);
	sprintf(testnameidx, ",%s,", testname);
	if (unwantedcolumn(hostname, testname) || (ignorecolumns && strstr(ignorecolumns, testnameidx))) {
		xfree(hostname);
		xfree(testname);
		xfree(testnameidx);
		if (fd) fclose(fd);
		return NULL;	/* Ignore this type of test */
	}
	xfree(testnameidx);

	newstate = (state_t *) calloc(1, sizeof(state_t));
	newstate->entry = (entry_t *) calloc(1, sizeof(entry_t));
	newstate->next = NULL;

	newstate->entry->column = find_or_create_column(testname, 1);
	newstate->entry->color = -1;
	strcpy(newstate->entry->age, "");
	newstate->entry->oldage = 0;
	newstate->entry->propagate = 1;
	newstate->entry->testflags = NULL;
	newstate->entry->skin = NULL;
	newstate->entry->repinfo = NULL;
	newstate->entry->causes = NULL;
	newstate->entry->histlogname = NULL;
	newstate->entry->shorttext = NULL;

	if (host) {
		newstate->entry->alert = checkalert(host->alerts, testname);

		/* If no WAP's specified, default all tests to be on WAP page */
		newstate->entry->onwap = (host->waps ? checkalert(host->waps, testname) : 1);
	}
	else {
		dbgprintf("   hostname %s not found\n", hostname);
		newstate->entry->alert = newstate->entry->onwap = 0;
	}

	newstate->entry->sumurl = NULL;

	if (reportstart) {
		/* Determine "color" for this test from the historical data */
		newstate->entry->repinfo = (reportinfo_t *) calloc(1, sizeof(reportinfo_t));
		newstate->entry->color = parse_historyfile(fd, newstate->entry->repinfo, 
				(dynamicreport ? NULL: hostname), (dynamicreport ? NULL : testname), 
				reportstart, reportend, 0, 
				(host ? host->reportwarnlevel : reportwarnlevel), 
				reportgreenlevel,
				(host ? host->reportwarnstops : reportwarnstops), 
				(host ? host->reporttime : NULL));
		newstate->entry->causes = (dynamicreport ? NULL : save_replogs());
	}
	else if (snapshot) {
		time_t fileage = snapshot - histentry_start;

		newstate->entry->color = history_color(fd, snapshot, &histentry_start, &newstate->entry->histlogname);

		newstate->entry->oldage = (fileage >= recentgif_limit);
		newstate->entry->fileage = fileage;
		strcpy(newstate->entry->age, agestring(fileage));
	}
	else {
		time_t fileage = (now - log->lastchange);

		newstate->entry->color = log->color;
		newstate->entry->testflags = strdup(log->testflags);
		if (testflag_set(newstate->entry, 'D')) newstate->entry->skin = dialupskin;
		if (testflag_set(newstate->entry, 'R')) newstate->entry->skin = reverseskin;
		newstate->entry->shorttext = strdup(log->msg);
		newstate->entry->acked = isacked;

		newstate->entry->oldage = (fileage >= recentgif_limit);
		newstate->entry->fileage = (log->lastchange ? fileage : -1);
		if (log->lastchange == 0)
			strcpy(newstate->entry->age, "");
		else 
			strcpy(newstate->entry->age, agestring(fileage));
	}

	if (purplelog && (newstate->entry->color == COL_PURPLE)) {
		fprintf(purplelog, "%s %s%s\n", 
		       hostname, testname, (host ? " (expired)" : " (unknown host)"));
	}

	newstate->entry->propagate = propagating;

	dbgprintf("init_state: hostname=%s, testname=%s, color=%d, acked=%d, age=%s, oldage=%d, propagate=%d, alert=%d\n",
		textornull(hostname), textornull(testname), 
		newstate->entry->color, newstate->entry->acked,
		textornull(newstate->entry->age), newstate->entry->oldage,
		newstate->entry->propagate, newstate->entry->alert);

	if (host) {
        	hostlist_t *l;

		/* Add this state entry to the host's list of state entries. */
		newstate->entry->next = host->entries;
		host->entries = newstate->entry;

		/* There may be multiple host entries, if a host is
		 * listed in several locations in bb-hosts (for display purposes).
		 * This is handled by updating ALL of the cloned host records.
		 * Bug reported by Bluejay Adametz of Fuji.
		 */

		/* Cannot use "find_host()" here, as we need the hostlink record, not the host record */
		l = find_hostlist(hostname);

		/* Walk through the clone-list and set the "entries" for all hosts */
		for (l=l->clones; (l); l = l->clones) l->hostentry->entries = host->entries;
	}
	else {
		/* No host for this test - must be missing from bb-hosts */
		newstate->entry->next = NULL;
	}

	xfree(hostname);
	xfree(testname);
	if (fd) fclose(fd);

	return newstate;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
	char histlogfn[PATH_MAX];
	char tailcmd[PATH_MAX];
	FILE *fd;
	time_t start1d, start1w, start4w, start1y;
	reportinfo_t repinfo1d, repinfo1w, repinfo4w, repinfo1y, dummyrep;
	replog_t *log1d, *log1w, *log4w, *log1y;
	char *p;
	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 (strcmp(argv[argi], "--no-svcid") == 0) {
			wantserviceid = 0;
		}
	}

	redirect_cgilog("bb-hist");

	envcheck(reqenv);
	cgidata = cgi_request();
	parse_query();

	/* Build our own URL */
	sprintf(selfurl, "%s", histcgiurl(hostname, service));

	p = selfurl + strlen(selfurl);
	sprintf(p, "&amp;BARSUMS=%d", barsums);

	if (strlen(ip)) {
		p = selfurl + strlen(selfurl);
		sprintf(p, "&amp;IP=%s", ip);
	}

	if (entrycount) {
		p = selfurl + strlen(selfurl);
		sprintf(p, "&amp;ENTRIES=%d", entrycount);
	}
	else strcat(selfurl, "&amp;ENTRIES=ALL");

	if (usepct) {
		/* Must modify 4-week charts to be 5-weeks, or the last day is 19% of the bar */
		/*
		 * Percent-based charts look awful with 24 hours / 7 days / 28 days / 12 months as basis
		 * because these numbers dont divide into 100 neatly. So the last item becomes
		 * too large (worst with the 28-day char: 100/28 = 3, last becomes (100-27*3) = 19% wide).
		 * So adjust the periods to something that matches percent-based calculations better.
		 */
		len1d = 25; bartitle1d = "25 hour summary";
		len1w = 10; bartitle1w = "10 day summary";
		len4w = 33; bartitle4w = "33 day summary";
		len1y = 10; bartitle1y = "10 month summary";
	}

	sprintf(histlogfn, "%s/%s.%s", xgetenv("BBHIST"), commafy(hostname), service);
	fd = fopen(histlogfn, "r");
	if (fd == NULL) {
		errormsg("Cannot open history file");
	}

	log1d = log1w = log4w = log1y = NULL;
	if (req_endtime == 0) req_endtime = time(NULL);
	/*
	 * Calculate the beginning time of each colorbar. We go back the specified length
	 * of time, except 1 second - so days are from midnight -> 23:59:59 etc.
	 */
	start1d = calc_time(req_endtime, -len1d, ALIGN_HOUR,  END_UNCHANGED) + 1;
	start1w = calc_time(req_endtime, -len1w, ALIGN_DAY,   END_UNCHANGED) + 1;
	start4w = calc_time(req_endtime, -len4w, ALIGN_DAY,   END_UNCHANGED) + 1;
	start1y = calc_time(req_endtime, -len1y, ALIGN_MONTH, END_UNCHANGED) + 1;

	/*
	 * Collect data for the color-bars and summaries. Multiple scans over the history file,
	 * but doing it all in one go would be hideously complex.
	 */
	if (barsums & BARSUM_1D) {
		parse_historyfile(fd, &repinfo1d, NULL, NULL, start1d, req_endtime, 1, reportwarnlevel, reportgreenlevel, NULL);
		log1d = save_replogs();
	}

	if (barsums & BARSUM_1W) {
		parse_historyfile(fd, &repinfo1w, NULL, NULL, start1w, req_endtime, 1, reportwarnlevel, reportgreenlevel, NULL);
		log1w = save_replogs();
	}

	if (barsums & BARSUM_4W) {
		parse_historyfile(fd, &repinfo4w, NULL, NULL, start4w, req_endtime, 1, reportwarnlevel, reportgreenlevel, NULL);
		log4w = save_replogs();
	}

	if (barsums & BARSUM_1Y) {
		parse_historyfile(fd, &repinfo1y, NULL, NULL, start1y, req_endtime, 1, reportwarnlevel, reportgreenlevel, NULL);
		log1y = save_replogs();
	}

	if (entrycount == 0) {
		/* All entries - just rewind the history file and do all of them */
		rewind(fd);
		parse_historyfile(fd, &dummyrep, NULL, NULL, 0, time(NULL), 1, reportwarnlevel, reportgreenlevel, NULL);
		fclose(fd);
	}
	else {
		/* Last 50 entries - we cheat and use "tail" in a pipe to pick the entries */
		fclose(fd);
		sprintf(tailcmd, "tail -%d %s", entrycount, histlogfn);
		fd = popen(tailcmd, "r");
		if (fd == NULL) errormsg("Cannot run tail on the histfile");
		parse_historyfile(fd, &dummyrep, NULL, NULL, 0, time(NULL), 1, reportwarnlevel, reportgreenlevel, NULL);
		pclose(fd);
	}


	/* Now generate the webpage */
	printf("Content-Type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));

	generate_history(stdout, 
			 hostname, service, ip, req_endtime, 
			 start1d, &repinfo1d, log1d, 
			 start1w, &repinfo1w, log1w, 
			 start4w, &repinfo4w, log4w, 
			 start1y, &repinfo1y, log1y, 
			 entrycount, reploghead);

	return 0;
}