Package ZenRRD :: Module RRDUtil
[hide private]
[frames] | no frames]

Source Code for Module ZenRRD.RRDUtil

  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   
 14  __doc__ = """RRDUtil 
 15   
 16  Wrapper routines around the rrdtool library. 
 17  """ 
 18   
 19  import logging 
 20  log = logging.getLogger("zen.RRDUtil") 
 21   
22 -def _checkUndefined(x):
23 """ 24 Sanity check on the min, max values 25 26 @param x: RRD min or max value 27 @type x: number 28 @return: Either the number or 'U' (for undefined) 29 @rtype: number or string 30 """ 31 if x is None or x == '' or x == -1 or x == '-1': 32 return 'U' 33 return x
34 35 36
37 -class RRDUtil:
38 """ 39 Wrapper class around rrdtool 40 """ 41
42 - def __init__(self, defaultRrdCreateCommand, defaultCycleTime):
43 """ 44 Initializer 45 46 The RRD creation command is only used if the RRD file doesn't 47 exist and no rrdCommand was specified with the save() method. 48 49 @param defaultRrdCreateCommand: RRD creation command 50 @type defaultRrdCreateCommand: string 51 @param defaultCycleTime: expected time to periodically collect data 52 @type defaultCycleTime: integer 53 """ 54 self.defaultRrdCreateCommand = defaultRrdCreateCommand 55 self.defaultCycleTime = defaultCycleTime 56 self.dataPoints = 0 57 self.cycleDataPoints = 0
58 59
60 - def endCycle(self):
61 """ 62 Report on the number of data points collected in a cycle, 63 and reset the counter for a new cycle. 64 65 @return: number of data points collected during the cycle 66 @rtype: number 67 """ 68 result = self.cycleDataPoints 69 self.cycleDataPoints = 0 70 return result
71 72
73 - def performancePath(self, path):
74 """ 75 Given a path, return its location from $ZENHOME and the 76 perf/ directories. 77 78 @param path: name for a datapoint in a path (eg device/component/datasource_datapoint) 79 @type path: string 80 @return: absolute path 81 @rtype: string 82 """ 83 from Products.ZenModel.PerformanceConf import performancePath 84 return performancePath(path)
85 86
87 - def save(self, path, value, rrdType, rrdCommand=None, cycleTime=None, 88 min='U', max='U'):
89 """ 90 Save the value provided in the command to the RRD file specified in path. 91 92 If the RRD file does not exist, use the rrdType, rrdCommand, min and 93 max parameters to create the file. 94 95 @param path: name for a datapoint in a path (eg device/component/datasource_datapoint) 96 @type path: string 97 @param value: value to store into the RRD file 98 @type value: number 99 @param rrdType: RRD data type (eg ABSOLUTE, DERIVE, COUNTER) 100 @type rrdType: string 101 @param rrdCommand: RRD file creation command 102 @type rrdCommand: string 103 @param cycleTime: length of a cycle 104 @type cycleTime: number 105 @param min: minimum value acceptable for this metric 106 @type min: number 107 @param max: maximum value acceptable for this metric 108 @type max: number 109 @return: the parameter value converted to a number 110 @rtype: number or None 111 """ 112 import rrdtool, os 113 114 if value is None: return None 115 116 self.dataPoints += 1 117 self.cycleDataPoints += 1 118 119 if cycleTime is None: 120 cycleTime = self.defaultCycleTime 121 122 filename = self.performancePath(path) + '.rrd' 123 if not rrdCommand: 124 rrdCommand = self.defaultRrdCreateCommand 125 if not os.path.exists(filename): 126 log.debug("Creating new RRD file %s", filename) 127 dirname = os.path.dirname(filename) 128 if not os.path.exists(dirname): 129 os.makedirs(dirname, 0750) 130 131 min, max = map(_checkUndefined, (min, max)) 132 dataSource = 'DS:%s:%s:%d:%s:%s' % ('ds0', rrdType, 133 3*cycleTime, min, max) 134 rrdtool.create(filename, 135 "--step", str(cycleTime), 136 str(dataSource), *rrdCommand.split()) 137 138 if rrdType in ('COUNTER', 'DERIVE'): 139 try: 140 value = long(value) 141 except (TypeError, ValueError): 142 return None 143 else: 144 value = float(value) 145 try: 146 rrdtool.update(filename, 'N:%s' % value) 147 log.debug('%s: %r', filename, value) 148 except rrdtool.error, err: 149 # may get update errors when updating too quickly 150 log.error('rrdtool reported error %s %s', err, path) 151 152 if rrdType in ('COUNTER', 'DERIVE'): 153 startStop, names, values = \ 154 rrdtool.fetch(filename, 'AVERAGE', 155 '-s', 'now-%d' % (cycleTime*2), 156 '-e', 'now') 157 values = [ v[0] for v in values if v[0] is not None ] 158 if values: value = values[-1] 159 else: value = None 160 return value
161