Ignore:
Timestamp:
08/15/05 18:48:14 (8 years ago)
Author:
Michael Medin <michael@…>
Children:
f3db4e0
Parents:
24f7192
Message:

Alot of fixes and some changes (se changelog for details)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/CheckEventLog/CheckEventLog.cpp

    r24f7192 r237da21  
    66#include <strEx.h> 
    77#include <time.h> 
     8#include <utils.h> 
    89 
    910CheckEventLog gCheckEventLog; 
     
    3940class EventLogRecord { 
    4041  EVENTLOGRECORD *pevlr_; 
     42  DWORD currentTime_; 
    4143public: 
    42   EventLogRecord(EVENTLOGRECORD *pevlr) : pevlr_(pevlr) { 
     44  EventLogRecord(EVENTLOGRECORD *pevlr, DWORD currentTime) : pevlr_(pevlr), currentTime_(currentTime) { 
    4345  } 
    4446  inline DWORD timeGenerated() const { 
    45     return pevlr_->TimeGenerated; 
     47    return (currentTime_-pevlr_->TimeGenerated)*1000; 
    4648  } 
    4749  inline DWORD timeWritten() const { 
    48     return pevlr_->TimeWritten; 
     50    return (currentTime_-pevlr_->TimeWritten)*1000; 
    4951  } 
    5052  inline std::string eventSource() const { 
     
    121123 
    122124 
    123 struct searchQuery { 
    124     struct searchQueryItem { 
    125  
    126       typedef enum { 
    127         eventType,  
    128         eventSource,  
    129         timeWritten, 
    130         timeGenerated, 
    131         message, 
    132         none 
    133       } queryType; 
    134  
    135       typedef enum { out, in, undefined } filterType; 
    136  
    137       filterType filter_; 
    138       queryType queryType_; 
    139       DWORD dwValue_; 
    140       boost::regex regexp_; 
    141        
    142  
    143       searchQueryItem()  
    144         : queryType_(none), dwValue_(0), filter_(out)  
    145       {} 
    146       searchQueryItem(filterType filter, queryType type, std::string str)  
    147         : queryType_(type), dwValue_(0), filter_(filter) 
    148       { 
    149         switch (queryType_ ) { 
    150         case eventType: 
    151           dwValue_ = EventLogRecord::translateType(str); 
    152           break; 
    153  
    154         case timeGenerated: 
    155           dwValue_ = strEx::stoui_as_time(str)/1000; 
    156           break; 
    157  
    158         case eventSource: 
    159         case message: 
    160           try { 
    161             regexp_ = str; 
    162           } catch (const boost::bad_expression e) { 
    163             throw (std::string)"Invalid syntax in regular expression:" + str; 
    164           } 
    165           break; 
    166         } 
    167       } 
    168  
    169       searchQueryItem& operator=(const searchQueryItem &other) { 
    170         queryType_ = other.queryType_; 
    171         dwValue_ = other.dwValue_; 
    172         filter_ = other.filter_; 
    173         try { 
    174           regexp_ = other.regexp_; 
    175         } catch (const boost::bad_expression e) { 
    176           throw (std::string)"Invalid syntax in regular expression:" + other.toString(); 
    177         } 
    178         return *this; 
    179       } 
    180  
    181       bool match(DWORD now, const EventLogRecord &record) const { 
    182         switch (queryType_) { 
    183         case eventType: 
    184           return record.eventType() & dwValue_; 
    185  
    186         case eventSource: 
    187           if (regexp_.empty()) 
    188             return false; 
    189           return boost::regex_match(record.eventSource(), regexp_); 
    190  
    191         case timeWritten: 
    192           return record.timeWritten() < (now-dwValue_); 
    193  
    194         case timeGenerated: 
    195           return record.timeGenerated() < (now-dwValue_); 
    196  
    197         case message: 
    198           if (regexp_.empty()) 
    199             return false; 
    200           return boost::regex_match(record.enumStrings(), regexp_); 
    201  
    202         default: 
    203           return false; 
    204         } 
    205       } 
    206       std::string queryType2String(queryType query) const { 
    207         switch (queryType_) { 
    208         case eventType: 
    209           return "eventType"; 
    210         case eventSource: 
    211           return "eventSource"; 
    212         case timeWritten: 
    213           return "timeWritten"; 
    214         case timeGenerated: 
    215           return "timeGenerated"; 
    216         case message: 
    217           return "message"; 
    218         default: 
    219           return "unknown"; 
    220         } 
    221  
    222       } 
    223  
    224       std::string toString() const { 
    225         std::stringstream ss; 
    226         ss << " Type: " << queryType2String(queryType_) << " = " << dwValue_ << ", '" << regexp_ << "'"; 
    227         return ss.str(); 
    228       } 
    229     }; 
    230  
    231  
    232  
    233   unsigned int truncate; 
    234   unsigned warning_count; 
    235   unsigned critical_count; 
    236   bool descriptions; 
    237   std::list<searchQueryItem> queries; 
    238  
    239   searchQuery() : truncate(0), descriptions(false), warning_count(0), critical_count(0) {} 
    240  
    241   std::string toString() { 
    242     std::string ret; 
    243     for (std::list<searchQuery::searchQueryItem>::const_iterator cit = queries.begin(); cit != queries.end(); ++cit ) { 
    244       ret += (*cit).toString(); 
    245     } 
    246     return ret; 
    247   } 
    248  
     125struct eventlog_filter { 
     126  filters::filter_all_strings eventSource; 
     127  filters::filter_all_numeric<unsigned int, filters::handlers::eventtype_handler> eventType; 
     128  filters::filter_all_strings message; 
     129  filters::filter_all_times timeWritten; 
     130  filters::filter_all_times timeGenerated; 
     131 
     132  inline bool hasFilter() { 
     133    return eventSource.hasFilter() || eventType.hasFilter() || message.hasFilter() ||  
     134      timeWritten.hasFilter() || timeGenerated.hasFilter(); 
     135  } 
     136  bool matchFilter(const EventLogRecord &value) const { 
     137    if ((eventSource.hasFilter())&&(eventSource.matchFilter(value.eventSource()))) 
     138      return true; 
     139    else if ((eventType.hasFilter())&&(eventType.matchFilter(value.eventType()))) 
     140      return true; 
     141    else if ((message.hasFilter())&&(message.matchFilter(value.enumStrings()))) 
     142      return true; 
     143    else if ((timeWritten.hasFilter())&&(timeWritten.matchFilter(value.timeWritten()))) 
     144      return true; 
     145    else if ((timeGenerated.hasFilter())&&(timeGenerated.matchFilter(value.timeGenerated()))) 
     146      return true; 
     147    return false; 
     148  } 
    249149}; 
    250150 
    251 // checkEventLog file=application truncate=1024 descriptions filter=[out|in] 
    252 //          warning-count=3 critical-count=10 
    253 // filter type = warning AND generated > 1d 
    254 // 
    255 // match (type, "warning") && match(generated, "1d") 
    256 //          filer-eventType=warning  
    257 //          filer-eventSource= 
    258 //          filer-date=4d 
    259 // 
    260 // CheckEventLog 
    261 // request: CheckEventLog&<logfile>&<Query strings> 
    262 // Return: <return state>&<log entry 1> - <log entry 2>... 
    263 // <return state> 0 - No errors 
    264 //          1 - Unknown 
    265 //          2 - Errors 
    266  
    267 // ./nrpe-2.0/src/check_nrpe -H 192.168.167 -p 5666 -c checkEventLog -a file=system file=application filter-eventType=warning filter-generated=1d descriptions filter-eventSource=Cdrom filter-eventSource=NSClient warning-count=3 critical-count=7 filter=in truncate=512 
    268 // 
    269 // Examples: 
    270 // CheckEventLog&Application&1&<type>&<query>&huffa... 
    271 // CheckEventLog&Application&warn.require.eventType=warning&critical.require.eventType=error&truncate=1024&descriptions&all.exclude.eventSourceRegexp=^(Win|Msi|NSClient\+\+|Userenv|ASP\.NET|LoadPerf|Outlook|Application E|NSClient).* 
     151 
     152#define MAP_FILTER(value, obj) \ 
     153      else if (p__.first == value) { eventlog_filter filter; filter.obj = p__.second; filter_chain.push_back(filter); } 
     154 
     155 
    272156#define BUFFER_SIZE 1024*64 
    273157NSCAPI::nagiosReturn CheckEventLog::handleCommand(const strEx::blindstr command, const unsigned int argLen, char **char_args, std::string &message, std::string &perf) { 
    274158  if (command != "CheckEventLog") 
    275159    return NSCAPI::returnIgnored; 
    276   NSCAPI::nagiosReturn rCode = NSCAPI::returnOK; 
    277   std::list<std::string> args = arrayBuffer::arrayBuffer2list(argLen, char_args); 
    278  
    279   std::string ret; 
    280   searchQuery query; 
     160  typedef checkHolders::CheckConatiner<checkHolders::MaxMinBoundsUInteger> EventLogQueryConatiner; 
     161  NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK; 
     162  std::list<std::string> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args); 
     163 
    281164  std::list<std::string> files; 
    282   searchQuery::searchQueryItem::filterType filter = searchQuery::searchQueryItem::out; 
    283  
    284   for (std::list<std::string>::const_iterator it = args.begin(); it!=args.end(); ++it) { 
    285     try { 
    286       if ((*it) == "descriptions") { 
    287         query.descriptions = true; 
    288       } else { 
    289         std::pair<std::string,std::string> p = strEx::split((*it), "="); 
    290         if (p.first == "truncate") { 
    291           query.truncate = strEx::stoi(p.second); 
    292         } else if (p.first == "file") { 
    293           files.push_back(p.second); 
    294         } else if (p.first == "filter") { 
    295           if (p.second == "in") 
    296             filter = searchQuery::searchQueryItem::in; 
    297           else 
    298             filter = searchQuery::searchQueryItem::out; 
    299         } else if (p.first == "warning-count") { 
    300           query.warning_count = strEx::stoi(p.second); 
    301         } else if (p.first == "critical-count") { 
    302           query.critical_count = strEx::stoi(p.second); 
    303  
    304         } else if (p.first == "filter-eventType") { 
    305           query.queries.push_back(searchQuery::searchQueryItem(filter, searchQuery::searchQueryItem::eventType, p.second)); 
    306         } else if (p.first == "filter-eventSource") { 
    307           query.queries.push_back(searchQuery::searchQueryItem(filter, searchQuery::searchQueryItem::eventSource, p.second)); 
    308         } else if (p.first == "filter-generated") { 
    309           query.queries.push_back(searchQuery::searchQueryItem(filter, searchQuery::searchQueryItem::timeGenerated, p.second)); 
    310         } else if (p.first == "filter-written") { 
    311           query.queries.push_back(searchQuery::searchQueryItem(filter, searchQuery::searchQueryItem::timeWritten, p.second)); 
    312         } else if (p.first == "filter-message") { 
    313           query.queries.push_back(searchQuery::searchQueryItem(filter, searchQuery::searchQueryItem::message, p.second)); 
    314         } 
    315       } 
    316     } catch (std::string s) { 
    317       if (message.empty()) 
    318         message += "UNKNOWN: "; 
    319       else 
    320         message += ", "; 
    321       message += s; 
    322     } 
    323   } 
    324   if (!message.empty()) { 
     165  std::list<eventlog_filter> filter_chain; 
     166  EventLogQueryConatiner query; 
     167 
     168  bool bFilterIn = true; 
     169  bool bFilterAll = false; 
     170  bool bShowDescriptions = false; 
     171  unsigned int truncate = 0; 
     172 
     173  try { 
     174    MAP_OPTIONS_BEGIN(stl_args) 
     175      MAP_OPTIONS_NUMERIC_ALL(query, "") 
     176      MAP_OPTIONS_STR2INT("truncate", truncate) 
     177      MAP_OPTIONS_BOOL_TRUE("descriptions", bShowDescriptions) 
     178      MAP_OPTIONS_PUSH("file", files) 
     179      MAP_OPTIONS_BOOL_EX("filter", bFilterIn, "in", "out") 
     180      MAP_OPTIONS_BOOL_EX("filter", bFilterAll, "all", "any") 
     181      MAP_FILTER("filter-eventType", eventType) 
     182      MAP_FILTER("filter-eventSource", eventSource) 
     183      MAP_FILTER("filter-generated", timeGenerated) 
     184      MAP_FILTER("filter-written", timeWritten) 
     185      MAP_FILTER("filter-message", message) 
     186      MAP_OPTIONS_MISSING(message, "Unknown argument: ") 
     187    MAP_OPTIONS_END() 
     188  } catch (filters::parse_exception e) { 
     189    message = e.getMessage(); 
     190    return NSCAPI::returnUNKNOWN; 
     191  } catch (filters::filter_exception e) { 
     192    message = e.getMessage(); 
    325193    return NSCAPI::returnUNKNOWN; 
    326194  } 
     
    352220      while (dwRead > 0)  
    353221      {  
    354         bool match = false; 
    355         bool undefined = true; 
    356         searchQuery::searchQueryItem::filterType tFilter = searchQuery::searchQueryItem::out; 
    357         EventLogRecord record(pevlr); 
    358  
    359         for (std::list<searchQuery::searchQueryItem>::const_iterator cit3 = query.queries.begin(); cit3 != query.queries.end(); ++cit3 ) { 
    360           if ((*cit3).match(currentTime, record)) { 
    361             if ((*cit3).filter_ == searchQuery::searchQueryItem::in) 
    362               match = true; 
    363             else { 
    364               match = false; 
     222        bool bMatch = bFilterAll; 
     223        EventLogRecord record(pevlr, currentTime); 
     224 
     225        for (std::list<eventlog_filter>::const_iterator cit3 = filter_chain.begin(); cit3 != filter_chain.end(); ++cit3 ) { 
     226          bool bTmpMatched = (*cit3).matchFilter(record); 
     227          if (bFilterAll) { 
     228            if (!bTmpMatched) { 
     229              bMatch = false; 
     230              break; 
     231            } 
     232          } else { 
     233            if (bTmpMatched) { 
     234              bMatch = true; 
     235              break; 
    365236            } 
    366237          } 
    367238        } 
    368239 
    369         if (match) { 
    370           if (!ret.empty()) 
    371             ret += ", "; 
    372           ret += record.eventSource(); 
    373           if (query.descriptions) { 
    374             ret += "(" + EventLogRecord::translateType(record.eventType()) + ")"; 
    375             ret += "[" + record.enumStrings() + "]"; 
     240        if ((bFilterIn&&bMatch)||(!bFilterIn&&!bMatch)) { 
     241          strEx::append_list(message, record.eventSource()); 
     242          if (bShowDescriptions) { 
     243            message += "(" + EventLogRecord::translateType(record.eventType()) + ")"; 
     244            message += "[" + record.enumStrings() + "]"; 
    376245          } 
    377246          hit_count++; 
    378247        } 
    379  
    380248        dwRead -= pevlr->Length;  
    381249        pevlr = (EVENTLOGRECORD *) ((LPBYTE) pevlr + pevlr->Length);  
    382250      }  
    383  
    384251      pevlr = (EVENTLOGRECORD *) &bBuffer;  
    385252    }  
    386  
    387253    CloseEventLog(hLog); 
    388254  } 
    389  
    390   if ((query.critical_count > 0) && (hit_count > query.critical_count)) { 
    391     ret = "CRITICAL: " + strEx::itos(hit_count) + " > critical: " + ret; 
    392     rCode = NSCAPI::returnCRIT; 
    393   } else if ((query.warning_count > 0) && (hit_count > query.warning_count)) { 
    394     ret = "WARNING: " + strEx::itos(hit_count) + " > warning: " + ret; 
    395     rCode = NSCAPI::returnWARN; 
    396   } else { 
    397     ret = "OK: " + strEx::itos(hit_count) + ": " + ret; 
    398   } 
    399   if (query.truncate != 0) 
    400     ret = ret.substr(0, query.truncate); 
    401   if ((query.truncate > 0) && (ret.length() > query.truncate)) 
    402     ret = ret.substr(0, query.truncate); 
    403   message = ret; 
    404   return rCode; 
     255  query.runCheck(hit_count, returnCode, message, perf); 
     256  if ((truncate > 0) && (message.length() > (truncate-4))) 
     257    message = message.substr(0, truncate-4) + "..."; 
     258  if (message.empty()) 
     259    message = "Eventlog check ok"; 
     260  return returnCode; 
    405261} 
    406262 
Note: See TracChangeset for help on using the changeset viewer.