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

Source Code for Module Products.ZenRRD.parsers.Nagios

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2008, 2009, all rights reserved. 
  4  #  
  5  # This content is made available according to terms specified in 
  6  # License.zenoss under the directory where your Zenoss product is installed. 
  7  #  
  8  ############################################################################## 
  9   
 10   
 11  """Nagios 
 12   
 13  Uses the Nagios API defintions from 
 14  http://nagios.sourceforge.net/docs/3_0/pluginapi.html and from 
 15  http://nagiosplug.sourceforge.net/developer-guidelines.html#PLUGOUTPUT 
 16  """ 
 17   
 18  import re 
 19   
 20  from Products.ZenUtils.Utils import getExitMessage 
 21  from Products.ZenRRD.CommandParser import CommandParser 
 22   
 23  # Performance datapoints syntax 
 24  # Matches substrings having the form <key>=<value> with optional trailing 
 25  # whitespace.  E.g. if this is the perf data: 
 26  # 
 27  #     rta=0.337000ms;180.000000;300.000000;0.000000 pl=0%;100;100;0. 
 28  # 
 29  # this is the output (using findall()): 
 30  # 
 31  # [('rta=0.337000ms;180.000000;300.000000;0.000000', 'rta', '', '0.337000'), 
 32  #  ('pl=0%;100;100;0', 'pl', '', '0')] 
 33  # 
 34  perfParser = re.compile(r"""(([^ =']+|'([^']+)')=([-0-9.eE]+)\S*)""") 
35 36 37 -class _BadData(Exception):
38 """ 39 Raised by splitMultLine when plugin output is not parseable. 40 """
41
42 43 -class Nagios(CommandParser):
44 45 @staticmethod
46 - def splitMultiLine(output):
47 """ 48 Convert the plugin output into component parts: 49 summary, performance_data 50 Empty output or no performance data raises a _BadData exception. 51 """ 52 output = output.strip() 53 if not output: 54 raise _BadData("No output from plugin") 55 56 # Expected format is: 57 # 58 # <text>|<perf data> 59 # <extra text> 60 # <extra text>|<extra perf data> 61 # <extra perf data> 62 # 63 # The first line has text and, optionally, perf data. Subsequent 64 # lines will have the format of <text>|<perf> across multiple lines. 65 lines = output.splitlines() 66 firstLine = lines[0].strip() 67 additionalLines = ' '.join(lines[1:]) 68 text, perf = [], [] 69 # Extract text and data from first line 70 segments = firstLine.split('|') 71 # If there are any segments, the first segment is text. 72 if segments: 73 text.append(segments.pop(0)) 74 # Extract additional text (due to bad pipe usage) 75 while len(segments) > 1: 76 text.append(segments.pop(0)) 77 # Extract the perf data (if exists) 78 if segments: 79 perf.append(segments.pop(0)) 80 # Now extract any additional data that may exist. 81 if additionalLines: 82 # Split text and perf data apart 83 segments = additionalLines.split('|') 84 # Extract text data (if any) 85 if segments: 86 text.extend(segments.pop(0).splitlines()) 87 # Extract perf data (if any) 88 if segments: 89 perf.extend(segments.pop(0).splitlines()) 90 91 # No perf data is an error 92 if not perf: 93 raise _BadData("No performance data from plugin") 94 95 return text, perf
96
97 - def processPerfData(self, rawPerfData):
98 """ 99 Create a dictionary of datapoint:value entries from 100 the plugin output. 101 This funtion removes a ' (represented as '' in the label) 102 from the label. There's just too much opportunity to mess 103 something up by keeping a shell meta-character. 104 """ 105 perfData = {} 106 all_data = ' '.join(rawPerfData) 107 # Strip out all '' strings 108 all_data = all_data.replace("''", "") 109 110 for _, label, quote_label, value in perfParser.findall(all_data): 111 if quote_label: 112 label = quote_label 113 try: 114 value = float(value.strip()) 115 except: 116 value = 'U' 117 perfData[label] = value 118 119 return perfData
120
121 - def processResults(self, cmd, result):
122 output = cmd.result.output 123 exitCode = cmd.result.exitCode 124 severity = cmd.severity 125 if exitCode == 0: 126 severity = 0 127 elif exitCode == 2: 128 severity = min(severity + 1, 5) 129 130 evt = { 131 "device": cmd.deviceConfig.device, 132 "message": output, 133 "severity": severity, 134 "component": cmd.component, 135 "eventKey": cmd.eventKey, 136 "eventClass": cmd.eventClass, 137 } 138 try: 139 summary, rawPerfData = self.splitMultiLine(output) 140 except _BadData as ex: 141 evt.update({ 142 "error_codes": "Datasource: %s - Code: %s - Msg: %s" % ( 143 cmd.name, exitCode, getExitMessage(exitCode) 144 ), 145 "performanceData": None, 146 "summary": str(ex), 147 }) 148 else: 149 evt.update({ 150 "performanceData": rawPerfData, 151 "summary": summary, 152 }) 153 perfData = self.processPerfData(rawPerfData) 154 for dp in cmd.points: 155 if dp.id in perfData: 156 result.values.append((dp, perfData[dp.id])) 157 result.events.append(evt)
158