int history_color(FILE *fd, time_t snapshot, time_t *starttime, char **histlogname) { char l[MAX_LINE_LEN]; time_t duration; char colstr[MAX_LINE_LEN]; int color; char *p; *histlogname = NULL; scan_historyfile(fd, snapshot, snapshot, l, sizeof(l), starttime, &duration, colstr); strcat(colstr, " "); color = parse_color(colstr); if ((color == COL_PURPLE) || (color == -1)) { color = -2; } p = timename(l); if (p) *histlogname = strdup(p); return color; }
int parse_historyfile(FILE *fd, reportinfo_t *repinfo, char *hostname, char *servicename, time_t fromtime, time_t totime, int for_history, double warnlevel, double greenlevel, int warnstops, char *reporttime) { char l[MAX_LINE_LEN]; time_t starttime, duration; unsigned int uistart, uidur; char colstr[MAX_LINE_LEN]; int color, done, i, scanres; int fileerrors = 0; repinfo->fstate = "OK"; repinfo->withreport = 0; repinfo->reportstart = getcurrenttime(NULL); for (i=0; (i<COL_COUNT); i++) { repinfo->count[i] = 0; repinfo->fullduration[i] = 0; repinfo->fullpct[i] = 0.0; repinfo->reportduration[i] = 0; repinfo->reportpct[i] = 0.0; } repinfo->fullavailability = 0.0; repinfo->reportavailability = 0.0; repinfo->fullstops = 0; repinfo->reportstops = 0; if (reporttime) build_reportspecs(reporttime); /* Sanity check */ if (totime > getcurrenttime(NULL)) totime = getcurrenttime(NULL); /* If for_history and fromtime is 0, dont do any seeking */ if (!for_history || (fromtime > 0)) { fileerrors = scan_historyfile(fd, fromtime, totime, l, sizeof(l), &starttime, &duration, colstr); } else { /* Already positioned (probably in a pipe) */ if (get_historyline(l, sizeof(l), fd, &fileerrors, colstr, &uistart, &uidur, &scanres)) { starttime = uistart; duration = uidur; if (scanres == 2) duration = getcurrenttime(NULL) - starttime; } else { starttime = getcurrenttime(NULL); duration = 0; strcpy(colstr, "clear"); fileerrors = 1; } } if (starttime > totime) { repinfo->fullavailability = repinfo->reportavailability = 100.0; repinfo->fullpct[COL_CLEAR] = repinfo->reportpct[COL_CLEAR] = 100.0; repinfo->count[COL_CLEAR] = 1; return COL_CLEAR; } /* If event starts before our fromtime, adjust starttime and duration */ if (starttime < fromtime) { duration -= (fromtime - starttime); starttime = fromtime; } repinfo->reportstart = starttime; done = 0; do { /* If event ends after our reportend, adjust duration */ if ((starttime + duration) > totime) duration = (totime - starttime); strcat(colstr, " "); color = parse_color(colstr); if (color != -1) { unsigned long sladuration = 0; dbgprintf("In-range entry starting %lu lasting %lu color %d: %s", starttime, duration, color, l); repinfo->count[color]++; repinfo->fullduration[color] += duration; if (color > COL_YELLOW) repinfo->fullstops++; if (reporttime) { sladuration = reportingduration(starttime, duration); repinfo->reportduration[color] += sladuration; if ((color > COL_YELLOW) && (sladuration > 0)) repinfo->reportstops++; } if (for_history || ((hostname != NULL) && (servicename != NULL))) { replog_t *newentry; char *timespec = timename(l); newentry = (replog_t *) malloc(sizeof(replog_t)); newentry->starttime = starttime; newentry->duration = duration; newentry->color = color; newentry->affectssla = (reporttime && (sladuration > 0)); if (!for_history && timespec && (color != COL_GREEN)) { newentry->cause = parse_histlogfile(hostname, servicename, timespec); } else newentry->cause = ""; newentry->timespec = (timespec ? strdup(timespec): NULL); newentry->next = reploghead; reploghead = newentry; } } if ((starttime + duration) < totime) { if (get_historyline(l, sizeof(l), fd, &fileerrors, colstr, &uistart, &uidur, &scanres)) { starttime = uistart; duration = uidur; if (scanres == 2) duration = getcurrenttime(NULL) - starttime; } else done = 1; } else done = 1; } while (!done); for (i=0; (i<COL_COUNT); i++) { dbgprintf("Duration for color %d: %lu\n", i, repinfo->fullduration[i]); repinfo->fullpct[i] = (100.0*repinfo->fullduration[i] / (totime - repinfo->reportstart)); } repinfo->fullavailability = 100.0 - repinfo->fullpct[COL_RED]; if (reporttime) { repinfo->withreport = 1; duration = repinfo->reportduration[COL_GREEN] + repinfo->reportduration[COL_YELLOW] + repinfo->reportduration[COL_RED] + repinfo->reportduration[COL_CLEAR]; if (duration > 0) { repinfo->reportpct[COL_GREEN] = (100.0*repinfo->reportduration[COL_GREEN] / duration); repinfo->reportpct[COL_YELLOW] = (100.0*repinfo->reportduration[COL_YELLOW] / duration); repinfo->reportpct[COL_RED] = (100.0*repinfo->reportduration[COL_RED] / duration); repinfo->reportpct[COL_CLEAR] = (100.0*repinfo->reportduration[COL_CLEAR] / duration); repinfo->reportavailability = 100.0 - repinfo->reportpct[COL_RED] - repinfo->reportpct[COL_CLEAR]; if (repinfo->reportavailability > greenlevel) color = COL_GREEN; else if (repinfo->reportavailability >= warnlevel) color = COL_YELLOW; else color = COL_RED; if ((warnstops >= 0) && (repinfo->reportstops > warnstops)) color = COL_RED; } else { /* Reporting period has no match with REPORTTIME setting */ repinfo->reportpct[COL_CLEAR] = 100.0; repinfo->reportavailability = 100.0; color = COL_GREEN; } } else { if (repinfo->fullavailability > greenlevel) color = COL_GREEN; else if (repinfo->fullavailability >= warnlevel) color = COL_YELLOW; else color = COL_RED; if ((warnstops >= 0) && (repinfo->fullstops > warnstops)) color = COL_RED; /* Copy the full percentages/durations to the SLA ones */ repinfo->reportavailability = repinfo->fullavailability; repinfo->reportstops = repinfo->fullstops; for (i=0; (i<COL_COUNT); i++) { repinfo->reportduration[i] = repinfo->fullduration[i]; repinfo->reportpct[i] = repinfo->fullpct[i]; } } if (fileerrors) repinfo->fstate = "NOTOK"; return color; }