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

Source Code for Module Products.ZenRRD.zenstep

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2007, 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  __doc__='''zenstep 
 12   
 13  Re-write an RRD files to have a different (larger) step. 
 14   
 15  $Id$ 
 16  ''' 
 17   
 18  import Globals 
 19  from Products.ZenModel.PerformanceConf import performancePath 
 20  from Products.ZenUtils.ZCmdBase import ZCmdBase 
 21   
 22  import os 
 23  from itertools import * 
 24  import rrdtool 
 25  import logging 
 26  log = logging.getLogger('zen.updateStep') 
 27   
28 -class UpdateStep(ZCmdBase):
29 """Run over the rrd files in a directory and write the data 30 into updated config files""" 31
32 - def processRRA(self, fullpath, rra, info, dump):
33 "process one archive in the file" 34 step = info['step'] 35 end = info['last_update'] 36 pdp_per_row = rra['pdp_per_row'] 37 rows = rra['rows'] 38 resolution = step*pdp_per_row 39 start = end - resolution*rows 40 start = start/resolution*resolution 41 end = end/resolution*resolution 42 data = rrdtool.fetch(fullpath, 43 'AVERAGE', 44 '--resolution', str(resolution), 45 '--start', str(start), 46 '--end', str(end)) 47 (start, end, resolution), unused, data = data 48 rnd = lambda x: x 49 if info['ds[ds0].type'] == 'COUNTER': 50 rnd = lambda x: int(x+0.5) 51 result = [] 52 for i, (v,) in enumerate(data): 53 if v != None: 54 dump[start + i*resolution] = rnd(v) 55 return result
56 57
58 - def process(self, fullpath):
59 "convert a single file" 60 log.debug("processing %s" % fullpath) 61 newpath = os.path.join(os.path.dirname(fullpath), 62 '.' + os.path.basename(fullpath)) 63 # get type, old step 64 info = rrdtool.info(fullpath) 65 dataType = info['ds[ds0].type'] 66 67 try: 68 os.unlink(newpath) 69 except OSError: 70 pass 71 72 rraList = [] 73 for rraIndex in count(): 74 rra = {} 75 rra['pdp_per_row'] = info.get('rra[%s].pdp_per_row' % rraIndex) 76 rra['rows'] = info.get('rra[%s].rows' % rraIndex) 77 if rra['pdp_per_row'] is None or rra['rows'] is None: 78 break 79 rraList.append(rra) 80 81 # Collect some information about the current file: 82 # how far back can the data go? 83 earliest = info['last_update'] 84 85 # how wide is the biggest data point? 86 biggest = 0 87 88 for rra in rraList: 89 size = rra['pdp_per_row'] * info['step'] 90 earliest = min(earliest, info['last_update'] - rra['rows'] * size) 91 biggest = max(biggest, size) 92 93 # create a file with the correct step to accept the data 94 rrdtool.create( 95 newpath, 96 'DS:ds0:%s:%d:U:U' % (dataType, biggest * 2), 97 '--start', str(earliest), 98 '--step', str(self.options.step), 99 *self.defaultRRDCommand.split()) 100 101 # extract the time and values from each archive 102 updates = {} 103 104 for rra in rraList: 105 self.processRRA(fullpath, rra, info, updates) 106 107 # get the times in order 108 updates = updates.items() 109 updates.sort() 110 rrdtool.update(newpath, *[('%d@%s' % (t, v)) for t, v in updates]) 111 # use a reasonable heartbeat 112 rrdtool.tune(newpath, '-h','ds0:%d' % (self.options.step*3)) 113 if self.options.commit: 114 os.rename(newpath, fullpath)
115 116
117 - def run(self):
118 monitors = self.dmd.Monitors.Performance 119 monitor = monitors._getOb(self.options.monitor) 120 self.defaultRRDCommand = monitor.getDefaultRRDCreateCommand() 121 if self.options.filename: 122 self.process(self.options.filename) 123 else: 124 for root, dirs, files in os.walk(self.options.root): 125 for filename in files: 126 # skip working files 127 if filename.startswith('.'): continue 128 if not filename.endswith('.rrd'): continue 129 fullpath = os.path.join(root, filename) 130 self.process(fullpath)
131 132
133 - def buildOptions(self):
134 ZCmdBase.buildOptions(self) 135 self.parser.add_option('-s', '--step', dest='step', type='int', 136 default=300, help='Default step size in seconds') 137 self.parser.add_option('-r', '--root', dest='root', 138 default=performancePath(''), 139 help='Root tree to convert') 140 self.parser.add_option('-f', '--file', dest='filename', 141 help='Root tree to convert') 142 self.parser.add_option('--commit', dest='commit', action='store_true', 143 default=False, 144 help='Really put the converted files in place.') 145 self.parser.add_option('--monitor', dest='monitor', 146 default='localhost', 147 help='Name of this collection host.')
148 149 if __name__ == '__main__': 150 us = UpdateStep() 151 us.run() 152