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

Source Code for Module Products.ZenRRD.ComponentCommandParser

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2008, 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  from Products.ZenRRD.CommandParser import CommandParser 
 12  from Products.ZenUtils.Utils import prepId as globalPrepId 
 13  import re 
 14  from pprint import pformat 
 15  import logging 
 16   
 17  log = logging.getLogger("zen.ComponentCommandParser") 
 18   
 19  # A 'dp' proxy object from the COMMAND zenhub service CommandPerformanceConfig 
 20  # contains: 
 21  # 
 22  # id                   - name of the datapoint 
 23  # component            - name of the component 
 24  # rrdPath              - path to filename 
 25  # rrdType              - eg GAUGE, DERIVE 
 26  # rrdCreateCommand     - how to create the RRD file if there isn't one 
 27  # rrdMin               - min value 
 28  # rrdMax               - max value 
 29  # data                 - result of parser.dataForParser(comp, dp) 
 30   
31 -class ComponentCommandParser(CommandParser):
32 33 # This default equates a 'part' of the output as being a line. 34 # In other words, assume one line has data about one component. 35 componentSplit = '\n' 36 37 # This item helps to find the component name in a 'part' (ie a line) 38 # This MUST contain a regex which has a regex item called 'component'. 39 # 40 # eg componentScanner = '% (?P<component>/.*)' 41 # 42 # The above says that a component entry starts with a '%' 43 componentScanner = '' 44 45 # Once we've found a part that contains component data, a scanner 46 # regex is used to match the part and return the name of the datapoint 47 # to which the value should be stored. 48 # 49 # Scanners are regexes with regex search matches. eg 50 # r' (?P<totalBlocks>\d+) +(?P<usedBlocks>\d+) ' 51 scanners = () 52 53 # What is the attribute of the component that matches the name from the command? 54 # This will be used in the zenhub service to grab the attribute value. 55 # 56 # If this is 'id', then run prepId on the command output to match the name in ZODB. 57 # Otherwise, the component name is assumed to not require cleaning. 58 # Components with non-HTML friendly bits in them (eg ':?%/') will 59 # need to be cleaned. Examples are things like filesystems. 60 componentScanValue = 'id' 61
62 - def prepId(self, id, subchar='_'):
63 return globalPrepId(id, subchar)
64
65 - def dataForParser(self, context, dp):
66 # This runs in the zenhub service, so it has access to the actual ZODB object 67 return dict(componentScanValue = getattr(context, self.componentScanValue))
68
69 - def processResults(self, cmd, result):
70 71 # Use the data from our proxy object to create a mapping from 72 # the component name to datapoints. 73 ifs = {} 74 for dp in cmd.points: 75 dp.component = dp.data['componentScanValue'] 76 points = ifs.setdefault(dp.component, {}) 77 points[dp.id] = dp 78 79 # Split command output into parts (typically lines) 80 parts = cmd.result.output.split(self.componentSplit) 81 82 for part in parts: 83 # Does this part (eg line) contain a component or not? 84 match = re.search(self.componentScanner, part) 85 if not match: 86 continue 87 88 # Search for the componentScanner regex 'component' item 89 component = match.groupdict()['component'].strip() 90 if self.componentScanValue == 'id': 91 component = self.prepId(component) 92 93 points = ifs.get(component, None) 94 if not points: 95 continue 96 97 # Use the scanners to search for datapoints 98 for search in self.scanners: 99 match = re.search(search, part) 100 if match: 101 for name, value in match.groupdict().items(): 102 dp = points.get(name, None) 103 if dp is not None: 104 if value in ('-', ''): value = 0 105 result.values.append( (dp, float(value) ) ) 106 107 log.debug(pformat(result)) 108 return result
109