/* $Header: /home/vikas/src/nocol/lib/RCS/event_utils.c,v 1.7 2000/01/19 03:39:47 vikas Exp $ */ /* Copyright 1993, JvNCnet */ /* * Small collection of common routines for the NOCOL monitors, etc. * * $Log: event_utils.c,v $ * Revision 1.7 2000/01/19 03:39:47 vikas * Patch by dbird@varadm.com for event_to_logstr() since tm_wday * can be negative and can core. Now using mktime(). * * Revision 1.6 1999/01/11 06:11:52 vikas * Was always picking up the current 'day' in event_to_logstr(). Now * trying to guess the day of the event. * Still needs more work since cannot handle events in the prev month. * * Revision 1.5 1998/07/23 15:08:41 vikas * Set the tm->tm_sec to zero since we dont keep track of secs. * * Revision 1.4 1994/05/16 01:50:11 vikas * Changed ESC_SEVERITY and update_event(). Now takes into account that * the max severity could have reduced in each call. Also logs at the * prev severity every time the severity changes (doesnt look at the * up/down status only). Thus, if a event goes from Critical -> Error, * update_event() will log that. * * Revision 1.3 1993/10/30 03:24:58 aggarwal * Added check for bad or illegal severity values. * * */ #include "nocol.h" #include /*+ * FUNCTION: * Skip leading spaces. */ char * skip_spaces(str) char *str ; { if (str == NULL) return (str); while (*str == ' ' || *str == '\t') ++str ; /* skip leading spaces */ return(str) ; } /* * Macro to escalate the severity of a site. */ #define ESC_SEVERITY(sev,maxs) (sev > maxs) ? (sev - 1) : maxs /*+ FUNCTION: * To update the event structure and log to noclogd based on the * 'status' (0 or 1) and 'value' which is simply inserted. * The severity is escalated if the status is down till it * reaches 'maxsev'. It is reduced if it exceeds maxseverity (very * possible in situations where you have multiple threshold levels * for warning, error, critical). * * The 'loglevel' is set to the more severe of the old/new severity * level. This is done so that if a site goes critical and is * logged at priority CRITICAL, then when it comes back up, it * is logged at priority CRITICAL also. * * Time is updated only when status is up or when the severity changes. */ update_event(v, status, value, maxsev) EVENT *v; int status; /* site status */ u_long value; /* event value */ int maxsev ; /* max severity */ { int oseverity = v->severity ; /* old severity */ struct tm *ltime ; time_t locclock ; /* careful: don't use 'long' */ locclock = time((time_t *) NULL); ltime = localtime((long *)&locclock); v->var.value = (u_long)value ; /* update value */ switch (status) { case 1: /* Site responded, is up */ /* always update time */ v->mon = ltime->tm_mon + 1; v->day = ltime->tm_mday; v->hour = ltime->tm_hour; v->min = ltime->tm_min; if (!(v->nocop & n_UP)) /* recent change of state */ { v->nocop = SETF_UPDOUN(v->nocop, n_UP) ; v->loglevel = v->severity; /* log at earlier level */ v->severity = E_INFO ; /* change severity */ eventlog(v); } break; case 0: /* site down, escalate the severity */ v->severity = ESC_SEVERITY(v->severity, maxsev); if (v->severity != oseverity) /* change in severity, hi or low */ { v->mon = ltime->tm_mon + 1; v->day = ltime->tm_mday; v->hour = ltime->tm_hour; v->min = ltime->tm_min; v->nocop = SETF_UPDOUN (v->nocop, n_DOWN); v->loglevel = v->severity < oseverity ? v->severity : oseverity; eventlog(v); } break; } /* end switch */ } /* update_event() */ /* */ /*+ event_to_logstr() ** FUNCTION: ** Formats an event structure as an ascii string that is written ** out to the various logfiles. Change here to get different ** format log lines. Not using EFMT, etc. since the log lines ** can have a TAG and other strings that might not be displayed. ** ** Note that you should not change this function because ** report generating functions might depend on this format. **/ char *event_to_logstr(v) EVENT *v ; { register int i ; static char fmts[512]; /* Okay, so its a looonnng string !! */ char nocops[32]; char datestr[32] ; struct tm *tm, tmn ; time_t locclock ; if (v == NULL) return ("\n"); /* * Create a string from the nocops flag */ *nocops = '\0'; for (i=0 ; *(nocop_txt[i].str) != '\0' ; ++i) if (v->nocop & nocop_txt[i].v) strcat(strcat(nocops, nocop_txt[i].str), " ") ; if (*nocops) *(nocops + strlen(nocops) - 1) = '\0' ; /* strip trailing blank */ /* * Format the date string. Do any date format conversions here */ /* * Convert into Unix asctime format, Note that we do not store * the year, etc. in nocol, so will get error if we have one year * old events. */ locclock = time((time_t *) NULL); tm = localtime((long *)&locclock); /* gets the year, etc. */ if (v->mon == 0 || v->day == 0) /* cannot be zero */ fprintf(stderr, "(event_to_logstr): Bad date (zeroes), setting to current\n"); else { /* contruct date of event */ bzero ((void *)&tmn, sizeof(tmn)); tmn.tm_year = tm->tm_year; /* assume same year */ tmn.tm_mon = v->mon - 1 ; tmn.tm_mday = v->day ; tmn.tm_hour = v->hour; tmn.tm_min = v->min ; tmn.tm_sec = 0; /* since we dont keep track of secs in nocol */ tmn.tm_isdst = -1; /* daylight savings time info not avilable */ /* adjust year if month is lower */ if (tm->tm_mon < tmn.tm_mon) --(tmn.tm_year); locclock = mktime(&tmn); /* */ tm = localtime((long *)&locclock); /* tm now contains the correct time for the event */ } sprintf(datestr, "%s", (char *)asctime(tm) ); *(strchr(datestr, '\n')) = '\0' ; /* delete the newline */ /* sprintf(datestr,"%02d/%02d %02d:%02d\0",v->mon,v->day,v->hour,v->min);/* */ if (v->severity < E_CRITICAL || v->severity > E_INFO) { fprintf(stderr, "(event_to_logstr): Bad severity %d, setting to CRITICAL\n", v->severity); v->severity = E_CRITICAL ; } if (v->loglevel < E_CRITICAL || v->loglevel > E_INFO) { fprintf(stderr, "(event_to_logstr): Bad loglevel %d, setting to CRITICAL\n", v->loglevel); v->loglevel = E_CRITICAL ; } /* * IF YOU CHANGE THIS LINE, CHANGE THE CORRESPONDING CODE IN * logstr_to_event() */ sprintf(fmts, "%s [%s]: SITE %s %s VAR %s %ld %ld %s LEVEL %s LOGLEVEL %s NOCOP %s\n", datestr, v->sender, v->site.name, v->site.addr, v->var.name, v->var.value, v->var.threshold, v->var.units, severity_txt[v->severity], severity_txt[v->loglevel], nocops) ; return(fmts) ; } /*+ logstr_to_event * FUNCTION: * Read in a line of the logstr format and create a nocol * EVENT structure out of it. * WILL NEED TO CHANGE IF THE logstr_format() FUNCTION CHANGES. */ EVENT *logstr_to_event(s) char *s ; /* text string with the nocol fields */ { static char *monthlist[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"} ; int a, b, c ; /* for scanning dates */ char *psender, *psite, *pvar, *plevel, *ploglevel, *pnocop ; char tmps[32], *tstr; register int i; static EVENT v ; /* needs to be static */ time_t nsecs ; struct tm *ptm ; psender = strstr(s, "[") ; ++psender ; /* skip past '[' */ psite = strstr(s, "SITE") ; pvar = strstr(s, "VAR") ; plevel = strstr(s, "LEVEL") ; ploglevel = strstr(s, "LOGLEVEL") ; pnocop = strstr(s, "NOCOP") ; /* * Parse date */ for (i=0; s[i] != '[' ; ++i ) /* try to grab the date part */ tmps[i] = s[i]; tmps[i] = '\0' ; while (tmps[--i] == ' ') /* delete trailing spaces */ tmps[i] = '\0'; /* * Calling get_date for robustness in parsing date's of various formats. */ /* nsecs = get_date(tmps); * fprintf(stderr, "Converted date '%s'\n", ctime(&nsecs)); * ptm = localtime((time_t)nsecs) ; * v.mon = ptm->tm_mon + 1; v.day = ptm->tm_mday; * v.hour = ptm->tm_hour; v.min = ptm->tm_min ; */ /** Parse date: Tue Sep 24 14:10:26 1993 **/ tstr = strchr(tmps, ' '); /* Get to the month string */ tstr = skip_spaces(tstr); for (v.mon=0 ;v.mon <12 && strncmp(tstr,monthlist[v.mon],3) != 0 ; ++v.mon) ; if (v.mon < 12) v.mon++ ; /* from 1 to 12 instead of 0-11 */ else { fprintf(stderr, "Error (scan_logstr_format): Bad month in date string '%s'\n", tstr); return (NULL); } /* sscanf(tstr, "%*s %d %d:%d", v.day, (v.hour), (v.min) ); /* skip month */ sscanf (tstr, "%*s %d %d:%d", &a, &b, &c); v.day = a ; v.hour = b ; v.min = c; /* * Sender field (in the square brackets[]) */ for (i=0 ; psender[i] != ']' ; ++i) v.sender[i] = psender[i] ; v.sender[i] = '\0'; strtok (psite, " \t") ; /* Skip over keyword 'SITE' */ strcpy(v.site.name, strtok(NULL, " \t")); strcpy(v.site.addr, strtok(NULL, " \t")); /* hope no spaces in addr */ strtok(pvar, " \t"); /* Skip over keyword 'VAR' */ strcpy(v.var.name, strtok(NULL, " \t")); v.var.value = atol (strtok(NULL, " \t")); v.var.threshold = atol (strtok(NULL, " \t")); strcpy(v.var.units, strtok(NULL, " \t")) ; strtok (plevel, " \t"); /* skip leading keyword */ tstr = strtok(NULL, " \t"); for (a=E_CRITICAL ; severity_txt[a] != "" ; ++a) if (strncmp(severity_txt[a], tstr, strlen(severity_txt[a])) == 0) break; v.severity = a ; strtok(ploglevel, " \t"); /* skip leading keyword */ tstr = strtok(NULL, " \t"); for (a=E_CRITICAL ; severity_txt[a] != "" ; ++a) if (strncasecmp(severity_txt[a], tstr, strlen(severity_txt[a])) == 0) break; v.loglevel = a ; strtok(pnocop, " \t"); /* Skip over keyword */ v.nocop = 0; while ((tstr = strtok(NULL, " \t")) != NULL) { register i = 0; while (nocop_txt[i].str != "") if (strncasecmp(nocop_txt[i].str, tstr, strlen(nocop_txt[i].str)) == 0) { v.nocop = v.nocop | nocop_txt[i].v ; break; } else ++i ; } #ifdef DEBUG fprintf(stderr, "(debug): %s\n", event_to_logstr(&v)) ; /* */ #endif return(&v) ; } /* end: logstr_to_event() */