Logo Search packages:      
Sourcecode: hobbit version File versions  Download package

eventlog.c

/*----------------------------------------------------------------------------*/
/* Hobbit monitor library.                                                    */
/*                                                                            */
/* This displays the "eventlog" found on the "All non-green status" page.     */
/* It also implements a CGI tool to show an eventlog for a given period of    */
/* time, as a reporting function.                                             */
/*                                                                            */
/* Copyright (C) 2002-2006 Henrik Storner <henrik@storner.dk>                 */
/* Host/test/color/start/end filtering code by Eric Schwimmer 2005            */
/*                                                                            */
/* This program is released under the GNU General Public License (GPL),       */
/* version 2. See the file "COPYING" for details.                             */
/*                                                                            */
/*----------------------------------------------------------------------------*/

static char rcsid[] = "$Id: eventlog.c,v 1.37 2006/07/20 22:07:47 henrik Rel $";

#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>

#include <pcre.h>

#include "libbbgen.h"

char *eventignorecolumns = NULL;
int havedoneeventlog = 0;

static int wanted_eventcolumn(char *service)
{
      char svc[100];
      int result;

      if (!eventignorecolumns || (strlen(service) > (sizeof(svc)-3))) return 1;

      sprintf(svc, ",%s,", service);
      result = (strstr(eventignorecolumns, svc) == NULL);

      return result;
}

static time_t convert_time(char *timestamp)
{
      time_t event = 0;
      unsigned int year,month,day,hour,min,sec,count;
      struct tm timeinfo;

      count = sscanf(timestamp, "%u/%u/%u@%u:%u:%u",
            &year, &month, &day, &hour, &min, &sec);
      if(count != 6) {
            return -1;
      }
      if(year < 1970) {
            return 0;
      }
      else {
            memset(&timeinfo, 0, sizeof(timeinfo));
            timeinfo.tm_year  = year - 1900;
            timeinfo.tm_mon   = month - 1;
            timeinfo.tm_mday  = day;
            timeinfo.tm_hour  = hour;
            timeinfo.tm_min   = min;
            timeinfo.tm_sec   = sec;
            timeinfo.tm_isdst = -1;
            event = mktime(&timeinfo);          
      }

      return event;
}

static htnames_t *namehead = NULL;
static htnames_t *getname(char *name, int createit)
{
      htnames_t *walk;

      for (walk = namehead; (walk && strcmp(walk->name, name)); walk = walk->next) ;
      if (walk || (!createit)) return walk;

      walk = (htnames_t *)malloc(sizeof(htnames_t));
      walk->name = strdup(name);
      walk->next = namehead;
      namehead = walk;

      return walk;
}


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)
{
      FILE *eventlog;
      char eventlogfilename[PATH_MAX];
      time_t firstevent = 0;
      time_t lastevent = time(NULL);
      event_t     *eventhead, *walk;
      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;

      havedoneeventlog = 1;

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

      if (fromtime) {
            firstevent = convert_time(fromtime);
            if(firstevent < 0) {
                  fprintf(output,"<B>Invalid 'from' time: %s</B>", fromtime);
                  return;
            }
      }
      else if (maxminutes) {
            firstevent = time(NULL) - maxminutes*60;
      }
      else {
            firstevent = time(NULL) - 86400;
      }

      if (totime) {
            lastevent = convert_time(totime);
            if (lastevent < 0) {
                  fprintf(output,"<B>Invalid 'to' time: %s</B>", totime);
                  return;
            }
            if (lastevent < firstevent) {
                  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("BBHIST"));
      eventlog = fopen(eventlogfilename, "r");

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

            /* 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); 
                        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);
                  }
                  else {
                        rewind(eventlog);
                        done = 1;
                  }
            } while (!done);
      }
      
      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, pagematch, hostmatch, testmatch, colrmatch;
            event_t *newevent;
            struct namelist_t *eventhost;
            struct htnames_t *eventcolumn;
            int ovector[30];

            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));
            if (eventtime > lastevent) break;
            eventhost = hostinfo(hostname);
            eventcolumn = getname(svcname, 1);

            if ( (itemsfound == 8) && 
                 (eventtime > firstevent) && 
                 (eventhost && !bbh_item(eventhost, BBH_FLAG_NOBB2)) && 
                 (wanted_eventcolumn(svcname)) ) {
                  if (ignoredialups && bbh_item(eventhost, BBH_FLAG_DIALUP)) continue;
                  if (hostcheck && (hostcheck(hostname) == 0)) continue;

                  if (pageregexp) {
                        char *pagename = bbh_item(eventhost, BBH_PAGEPATH);
                        pagematch = (pcre_exec(pageregexp, NULL, pagename, strlen(pagename), 0, 0, 
                                    ovector, (sizeof(ovector)/sizeof(int))) >= 0);
                  }
                  else
                        pagematch = 1;
                  if (!pagematch) continue;

                  if (expageregexp) {
                        char *pagename = bbh_item(eventhost, BBH_PAGEPATH);
                        pagematch = (pcre_exec(expageregexp, NULL, pagename, strlen(pagename), 0, 0, 
                                    ovector, (sizeof(ovector)/sizeof(int))) >= 0);
                  }
                  else
                        pagematch = 0;
                  if (pagematch) continue;

                  if (hostregexp)
                        hostmatch = (pcre_exec(hostregexp, NULL, hostname, strlen(hostname), 0, 0, 
                                    ovector, (sizeof(ovector)/sizeof(int))) >= 0);
                  else
                        hostmatch = 1;
                  if (!hostmatch) continue;

                  if (exhostregexp)
                        hostmatch = (pcre_exec(exhostregexp, NULL, hostname, strlen(hostname), 0, 0, 
                                    ovector, (sizeof(ovector)/sizeof(int))) >= 0);
                  else
                        hostmatch = 0;
                  if (hostmatch) continue;

                  if (testregexp)
                        testmatch = (pcre_exec(testregexp, NULL, svcname, strlen(svcname), 0, 0, 
                                    ovector, (sizeof(ovector)/sizeof(int))) >= 0);
                  else
                        testmatch = 1;
                  if (!testmatch) continue;

                  if (extestregexp)
                        testmatch = (pcre_exec(extestregexp, NULL, svcname, strlen(svcname), 0, 0, 
                                    ovector, (sizeof(ovector)/sizeof(int))) >= 0);
                  else
                        testmatch = 0;
                  if (testmatch) continue;

                  if (colrregexp) {
                        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 (eventhead) {
            char *bgcolors[2] = { "#000000", "#000033" };
            int  bgcolor = 0;
            int  count;
            struct event_t *lasttoshow = eventhead;

            count=0;
            walk=eventhead; 
            do {
                  count++;
                  lasttoshow = walk;
                  walk = walk->next;
            } while (walk && (count<maxcount));

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

            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", title);

            for (walk=eventhead; (walk != lasttoshow->next); walk=walk->next) {
                  char *hostname = bbh_item(walk->host, BBH_HOSTNAME);

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

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

                  if (walk->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(walk->newcolor), hostname);
                  }

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

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

            /* Clean up */
            walk = eventhead;
            do {
                  struct event_t *tmp = walk;

                  walk = walk->next;
                  xfree(tmp);
            } while (walk);
      }
      else {
            /* 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", 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);
}


Generated by  Doxygen 1.6.0   Back to index