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

Source Code for Module ZenRRD.zenstep

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