1
2
3
4
5
6
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
29 """Run over the rrd files in a directory and write the data
30 into updated config files"""
31
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
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
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
82
83 earliest = info['last_update']
84
85
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
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
102 updates = {}
103
104 for rra in rraList:
105 self.processRRA(fullpath, rra, info, updates)
106
107
108 updates = updates.items()
109 updates.sort()
110 rrdtool.update(newpath, *[('%d@%s' % (t, v)) for t, v in updates])
111
112 rrdtool.tune(newpath, '-h','ds0:%d' % (self.options.step*3))
113 if self.options.commit:
114 os.rename(newpath, fullpath)
115
116
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
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
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