Package ZenHub :: Package services :: Module RRDImpl
[hide private]
[frames] | no frames]

Source Code for Module ZenHub.services.RRDImpl

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, 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 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13  import os.path 
 14   
 15  from Products.ZenRRD.RRDUtil import RRDUtil 
 16   
 17  import logging 
 18  log = logging.getLogger("zenhub") 
 19   
 20   
21 -class RRDImpl:
22 # list of rrd types that only accept long or integer values (no floats!) 23 LONG_RRD_TYPES = ['COUNTER', 'DERIVE'] 24
25 - def __init__(self, dmd):
26 # rrd is a dictionary of RRDUtil instances 27 self.rrd = {} 28 # counts is a dictionary of integers tracking how many times 29 # each threshold has been exceeded sequentially. 30 self.counts = {} 31 32 self.dmd = dmd
33 34
35 - def writeRRD(self, devId, compType, compId, dpName, value):
36 ''' Write the given data to it's rrd file. 37 Also check any thresholds and send events if value is out of bounds. 38 ''' 39 log.debug('Writing %s %s' % (dpName, value)) 40 dev = self.getDeviceOrComponent(devId, compType, compId) 41 dp = dev.getRRDDataPoint(dpName) 42 if not dp: 43 log.warn('Did not find datapoint %s on device %s', dpName, devId) 44 return None 45 rrdKey = (dev.getPrimaryPath(), dp.getPrimaryPath()) 46 rrdCreateCmd = dp.createCmd or self.getDefaultRRDCreateCommand(dev) 47 if self.rrd.has_key(rrdKey): 48 rrd = self.rrd[rrdKey] 49 else: 50 rrd = RRDUtil(rrdCreateCmd, dp.datasource.cycletime) 51 self.rrd[rrdKey] = rrd 52 53 # convert value to a long if our data point uses a long type 54 if dp.rrdtype in RRDImpl.LONG_RRD_TYPES: 55 try: 56 value = long(value) 57 except ValueError: 58 log.warn("value '%s' received for data point '%s' that " \ 59 "could not be converted to a long" % \ 60 (value, dp.rrdtype)) 61 62 value = rrd.save(os.path.join(dev.rrdPath(), dp.name()), 63 value, 64 dp.rrdtype, 65 rrdCreateCmd, 66 dp.datasource.cycletime, 67 dp.rrdmin, 68 dp.rrdmax) 69 self.checkThresholds(dev, dp, value) 70 return value
71 72
73 - def getDefaultRRDCreateCommand(self, device):
74 return device.perfServer().getDefaultRRDCreateCommand()
75 76
77 - def getDeviceOrComponent(self, devId, compId, compType):
78 ''' If a compId is given then try to return that component. If unable 79 to find it or if compId is not specified then try to return the 80 given device. If unable to find then return None. 81 ''' 82 d = None 83 device = self.dmd.Devices.findDevice(devId) 84 if device: 85 if compId: 86 for comp in device.getDeviceComponents(): 87 if comp.meta_type == compType and comp.id == compId: 88 d = comp 89 break 90 else: 91 d = device 92 return d
93 94
95 - def checkThresholds(self, dev, dp, value):
96 ''' Check the given value against any thresholds. Count the number of 97 times a dp has exceeded a given threshold in self.counts. Send events 98 as appropriate. 99 ''' 100 if value is None: 101 return 102 # Loop through the enabled thresholds on the template containing 103 # this datapoint. 104 for t in [t for t in dp.datasource.rrdTemplate.thresholds() 105 if t.enabled and dp.name() in t.dsnames]: 106 log.debug('Checking %s value of %s against threshold %s: %s:%s' % 107 (dp.name(), value, t.id, t.getMinval(dev), t.getMaxval(dev))) 108 countKey = (dev.getPrimaryPath(), dp.getPrimaryPath(), t.id) 109 count = self.counts.setdefault(countKey, 0) 110 limit = None 111 how = None 112 maxv = t.getMaxval(dev) 113 if maxv is not None and value > maxv: 114 log.debug('threshold exceeded') 115 limit = maxv 116 how = 'exceeded' 117 else: 118 minv = t.getMinval(dev) 119 if minv is not None and value < minv: 120 log.debug('threshold not met') 121 limit = minv 122 how = 'not met' 123 # Only need to take action if threshold was exceeded or if it was 124 # previously exceeded. 125 if how or count: 126 if dev.meta_type == 'Device': 127 devId = dev.id 128 compId = '' 129 else: 130 devId = dev.device().id 131 compId = dev.id 132 if how: 133 self.counts[countKey] += 1 134 severity = t.severity 135 if t.escalateCount and count >= t.escalateCount: 136 severity += 1 137 summary = ('%s %s threshold of %s %s:' % 138 (devId, dp.name(), limit, how) + 139 ' current value %.2f' % float(value)) 140 else: 141 self.counts[countKey] = 0 142 severity = 0 143 summary = ('%s %s threshold restored' % 144 (devId, dp.name()) + 145 ' current value: %.2f' % float(value)) 146 self.zem.sendEvent(dict( 147 device=devId, 148 summary=summary, 149 eventClass=t.eventClass, 150 eventKey=dp.name(), 151 component=compId, 152 severity=severity))
153