class Nagios(object): key = "Nagios" def __init__(self, hostname): """hostname is the name of the machine where the nagios log lives """ # Regex alternation ends up being tricker than expected, and much less readable #self.re_line = re.compile('^\[(\d+)\] (?:EXTERNAL COMMAND: (\w+);)|(?:([^:]+): )(.*)$') self.re_line_reg = re.compile( '^\[(\d+)\] EXTERNAL COMMAND: (\w+);(.*)$') self.re_line_ext = re.compile('^\[(\d+)\] ([^:]+): (.*)$') self.logger = None self.gen = None self.tail = None self.events = None self.apikey = "" self.hostname = hostname self._line_parsed = 0 def _parse_line(self, line): """Actual nagios parsing Return True if we found an event, False otherwise """ # first isolate the timestamp and the event type try: self._line_parsed = self._line_parsed + 1 m = self.re_line_reg.match(line) if m is None: m = self.re_line_ext.match(line) if m is None: return False (tstamp, event_type, remainder) = m.groups() tstamp = int(tstamp) if event_type in IGNORE_EVENT_TYPES: self.logger.info("Ignoring nagios event of type %s" % (event_type)) return False # then retrieve the event format for each specific event type fields = EVENT_FIELDS.get(event_type, None) if fields is None: self.logger.warn("Ignoring unkown nagios event for line: %s" % (line[:-1])) return False # and parse the rest of the line parts = map(lambda p: p.strip(), remainder.split(';')) # Chop parts we don't recognize parts = parts[:len(fields._fields)] event = create_event(tstamp, event_type, self.hostname, fields._make(parts)) event.update({'api_key': self.apikey}) self.events.append(event) self.logger.debug("Nagios event: %s" % (event)) return True except Exception: self.logger.exception( "Unable to create a nagios event from line: [%s]" % (line)) return False def check(self, logger, agentConfig, move_end=True): self.logger = logger # Check arguments log_path = agentConfig.get('nagios_log', None) if log_path is None: self.logger.debug( "Not checking nagios because nagios_log is not set in config file" ) return False self.apikey = agentConfig['api_key'] self.events = [] self._line_parsed = 0 # Build our tail -f if self.gen is None: self.tail = TailFile(logger, log_path, self._parse_line) self.gen = self.tail.tail(line_by_line=False, move_end=move_end) # read until the end of file try: self.logger.debug("Start nagios check for file %s" % (log_path)) self.tail._log = self.logger self.gen.next() self.logger.debug( "Done nagios check for file %s (parsed %s line(s), generated %s event(s))" % (log_path, self._line_parsed, len(self.events))) except StopIteration, e: self.logger.exception(e) self.logger.warn("Can't tail %s file" % (log_path)) return self.events
class Nagios(object): key = "Nagios" def __init__(self, hostname): """hostname is the name of the machine where the nagios log lives """ # Regex alternation ends up being tricker than expected, and much less readable #self.re_line = re.compile('^\[(\d+)\] (?:EXTERNAL COMMAND: (\w+);)|(?:([^:]+): )(.*)$') self.re_line_reg = re.compile('^\[(\d+)\] EXTERNAL COMMAND: (\w+);(.*)$') self.re_line_ext = re.compile('^\[(\d+)\] ([^:]+): (.*)$') self.logger = None self.gen = None self.tail = None self.events = None self.apikey = "" self.hostname = hostname self._line_parsed = 0 def _parse_line(self, line): """Actual nagios parsing Return True if we found an event, False otherwise """ # first isolate the timestamp and the event type try: self._line_parsed = self._line_parsed + 1 m = self.re_line_reg.match(line) if m is None: m = self.re_line_ext.match(line) if m is None: return False (tstamp, event_type, remainder) = m.groups() tstamp = int(tstamp) if event_type in IGNORE_EVENT_TYPES: self.logger.info("Ignoring nagios event of type %s" % (event_type)) return False # then retrieve the event format for each specific event type fields = EVENT_FIELDS.get(event_type, None) if fields is None: self.logger.warn("Ignoring unkown nagios event for line: %s" % (line[:-1])) return False # and parse the rest of the line parts = map(lambda p: p.strip(), remainder.split(';')) # Chop parts we don't recognize parts = parts[:len(fields._fields)] event = create_event(tstamp, event_type, self.hostname, fields._make(parts)) event.update({'api_key': self.apikey}) self.events.append(event) self.logger.debug("Nagios event: %s" % (event)) return True except Exception: self.logger.exception("Unable to create a nagios event from line: [%s]" % (line)) return False def check(self, logger, agentConfig, move_end=True): self.logger = logger # Check arguments log_path = agentConfig.get('nagios_log',None) if log_path is None: self.logger.debug("Not checking nagios because nagios_log is not set in config file") return False self.apikey = agentConfig['api_key'] self.events = [] self._line_parsed = 0 # Build our tail -f if self.gen is None: self.tail = TailFile(logger,log_path,self._parse_line) self.gen = self.tail.tail(line_by_line=False, move_end=move_end) # read until the end of file try: self.logger.debug("Start nagios check for file %s" % (log_path)) self.tail._log = self.logger self.gen.next() self.logger.debug("Done nagios check for file %s (parsed %s line(s), generated %s event(s))" % (log_path,self._line_parsed,len(self.events))) except StopIteration, e: self.logger.exception(e) self.logger.warn("Can't tail %s file" % (log_path)) return self.events