Package Products :: Package ZenRRD :: Package parsers :: Module Nagios |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenRRD.parsers.Nagios

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2008, 2009 Zenoss Inc.
      5  #
      6  # This program is free software; you can redistribute it and/or modify it
      7  # under the terms of the GNU General Public License version 2 or (at your
      8  # option) any later version as published by the Free Software Foundation.
      9  #
     10  # For complete information please visit: http://www.zenoss.com/oss/
     11  #
     12  ###########################################################################
     13
     14  __doc__ = """Nagios
     15  Uses the Nagios API defintions from http://nagios.sourceforge.net/docs/3_0/pluginapi.html
     16  and from
     17  http://nagiosplug.sourceforge.net/developer-guidelines.html#PLUGOUTPUT
     18  """
     19
     20  import re
     21
     22  # Performance datapoints syntax
     23  perfParser = re.compile(r"""(([^ =']+|'([^']+)')=([-0-9.eE]+)\S*)""")
     24
     25  from Products.ZenUtils.Utils import getExitMessage
     26  from Products.ZenRRD.CommandParser import CommandParser
     27
     28 -class Nagios(CommandParser):
     29
     30 -    def splitMultiLine(self, output):
     31          """
     32          Convert the plugin output into component parts:
     33               summary, message, performance_data
     34
     35          If the message is None, then there is an error.
     36          """
     37          summary, msg, rawPerfData = "", [], []
     38          if not output.strip():
     39              return "No output from plugin", None, None
     40
     41          # Deal with the first line
     42          first_plus_rest = output.split('\n',1)
     43          firstLine = first_plus_rest[0].strip()
     44          if not firstLine:
     45              return "No output from plugin", None, None
     46
     47          summaryNPerf = firstLine.split('|')
     48          if len(summaryNPerf) > 2:
     49              return "Too many |'s in output from plugin", None, None
     50
     51          summary = summaryNPerf[0]
     52          # x = [] so x[1] is an error but x[1:] == []
     53          rawPerfData = summaryNPerf[1:]
     54
     55          # Is there a mult-line to deal with?
     56          multi = first_plus_rest[1:]
     57          if not multi: # Nope
     58              return summary, summary, rawPerfData
     59
     60          service_output_plus_perf = multi[0].split('|')
     61          if len(service_output_plus_perf) > 2:
     62              return "Too many |'s in output from plugin", None, None
     63
     64          msg = service_output_plus_perf[0]
     65          if len(service_output_plus_perf) == 2:
     66              rawPerfData += service_output_plus_perf[1].split('\n')
     67          return summary, msg, rawPerfData
     68
     69
     70 -    def processPerfData(self, rawPerfData):
     71          """
     72          Create a dictionary of datapoint:value entries from
     73          the plugin output.
     74          This funtion removes a ' (represented as '' in the label)
     75          from the label.  There's just too much opportunity to mess
     76          something up by keeping a shell meta-character.
     77          """
     78          perfData = {}
     79          all_data = ' '.join(rawPerfData)
     80          # Strip out all '' strings
     81          all_data = all_data.replace("''", "")
     82
     83          for full_match, label, quote_label, value in perfParser.findall(all_data):
     84              if quote_label:
     85                  label = quote_label
     86              try:
     87                  value = float(value.strip())
     88              except:
     89                  value = 'U'
     90              perfData[label] = value
     91
     92          return perfData
     93
     94
     95 -    def processResults(self, cmd, result):
     96          output = cmd.result.output
     97          exitCode = cmd.result.exitCode
     98          severity = cmd.severity
     99          if exitCode == 0:
    100              severity = 0
    101          elif exitCode == 2:
    102              severity = min(severity + 1, 5)
    103
    104          summary, msg, rawPerfData = self.splitMultiLine(output)
    105
    106          evt = dict(device=cmd.deviceConfig.device,
    107                summary=summary, message=output,
    108                severity=severity, component=cmd.component,
    109                eventKey=cmd.eventKey, eventClass=cmd.eventClass,
    110                performanceData=rawPerfData,
    111          )
    112
    113          if msg is None:
    114              evt['error_codes'] = 'Datasource: %s - Code: %s - Msg: %s' % (
    115                             cmd.name, exitCode,
    116                             getExitMessage(exitCode))
    117              result.events.append(evt)
    118              return
    119
    120          result.events.append(evt)
    121
    122          perfData = self.processPerfData(rawPerfData)
    123          for dp in cmd.points:
    124              if dp.id in perfData:
    125                  result.values.append( (dp, perfData[dp.id]) )
    126