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