| Trees | Indices | Help |
|---|
|
|
1 # -*- Mode: Python -*-
2 # vi:si:et:sw=4:sts=4:ts=4
3 #
4 # Flumotion - a streaming media server
5 # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com).
6 # All rights reserved.
7
8 # This file may be distributed and/or modified under the terms of
9 # the GNU General Public License version 2 as published by
10 # the Free Software Foundation.
11 # This file is distributed without any warranty; without even the implied
12 # warranty of merchantability or fitness for a particular purpose.
13 # See "LICENSE.GPL" in the source distribution for more information.
14
15 # Licensees having purchased or holding a valid Flumotion Advanced
16 # Streaming Server license may use this file in accordance with the
17 # Flumotion Advanced Streaming Server Commercial License Agreement.
18 # See "LICENSE.Flumotion" in the source distribution for more information.
19
20 # Headers in this file shall remain intact.
21
22 """RRD resource poller daemon for Flumotion.
23
24 Makes periodic observations on components' UI states, recording them to
25 RRD files. One can then extract graphs using rrdtool graph. For example,
26 to show a stream bandwidth graph for the last 30 minutes with the
27 example configuration file, in the source tree as
28 conf/rrdmon/default.xml, the following command makes a graph:
29
30 rrdtool graph --end now --start end-30min --width 400 out.png \
31 DEF:ds0=/tmp/stream-bitrate.rrd:http-streamer:AVERAGE \
32 AREA:ds0#0000FF:"Stream bandwidth (bytes/sec)"
33
34 It would be possible to expose these graphs via HTTP, but I don't know
35 how useful this might be.
36
37 See L{flumotion.admin.rrdmon.config} for information on how to configure
38 the RRD resource poller.
39 """
40
41 import os
42 import random
43 import rrdtool
44 import datetime
45 import time
46
47 from flumotion.admin import multi
48 from flumotion.common import log, common
49 from flumotion.common import eventcalendar
50 from flumotion.component.base import scheduler
51
52 # register the unjellyable
53 from flumotion.common import componentui
54
55 componentui # pyflakes
56
57 __version__ = "$Rev: 7587 $"
58
59
61 return source['rrd-file']
62
63
65 return source['name']
66
67
69 return source['sample-frequency']
70
71
73
74 def makeDS():
75 if source['is-gauge']:
76 return 'DS:%s:GAUGE:%d:U:U' % (source['name'],
77 2*source['sample-frequency'])
78 else:
79 return 'DS:%s:DERIVE:%d:0:U' % (source['name'],
80 2*source['sample-frequency'])
81 return source['rrd-ds-spec'] or makeDS()
82
83
88 return [archiveGetRRA(archive) for archive in source['archives']]
89
90
92 return source['manager']
93
94
96 return source['component-id']
97
98
100 return source['ui-state-key']
101
102
104 logName = 'rrdmon'
105
107 self.debug('started rrd monitor')
108 self.multi = multi.MultiAdminModel()
109 self.scheduler = scheduler.Scheduler()
110 self.ensureRRDFiles(sources)
111 self.connectToManagers(sources)
112 self.startScheduler(sources)
113
115 for source in sources:
116 rrdfile = sourceGetFileName(source)
117 if not os.path.exists(rrdfile):
118 try:
119 self.info('Creating RRD file %s', rrdfile)
120 rrdtool.create(rrdfile,
121 "-s", str(sourceGetSampleFrequency(source)),
122 sourceGetDS(source),
123 *sourceGetRRAList(source))
124 except rrdtool.error, e:
125 self.warning('Could not create RRD file %s',
126 rrdfile)
127 self.debug('Failure reason: %s',
128 log.getExceptionMessage(e))
129
131 for source in sources:
132 connectionInfo = sourceGetConnectionInfo(source)
133 self.multi.addManager(connectionInfo, tenacious=True)
134
136 r = random.Random()
137 now = datetime.datetime.now(eventcalendar.LOCAL)
138
139 def eventInstanceStarted(eventInstance):
140 self.pollData(*eventInstance.event.content)
141
142 def eventStopped(eventInstance):
143 pass
144
145 self.scheduler.subscribe(eventInstanceStarted, eventInstanceStopped)
146
147 for source in sources:
148 freq = sourceGetSampleFrequency(source)
149
150 # randomly offset the polling
151 offset = datetime.timedelta(seconds=r.randint(0, freq))
152
153 data = (str(sourceGetConnectionInfo(source)),
154 sourceGetComponentId(source),
155 sourceGetUIStateKey(source),
156 sourceGetName(source),
157 sourceGetFileName(source))
158
159 # FIXME: Event never actually allowed a timedelta as rrule,
160 # so I doubt this refactoring of scheduler ever worked
161 calendar = eventcalendar.Calendar()
162 calendar.addEvent(now.isoformat(),
163 now + offset, now + offset + datetime.timedelta(seconds=1),
164 data, rrule=datetime.timedelta(seconds=freq))
165 self.scheduler.setCalendar(calendar)
166
172
173 if managerId in self.multi.admins:
174 admin = self.multi.admins[managerId]
175
176 flowName, componentName = common.parseComponentId(componentId)
177
178 flows = stateListToDict(admin.planet.get('flows'))
179 if flowName not in flows:
180 self.warning('not polling %s%s:%s: no such flow %s',
181 managerId, componentId, uiStateKey,
182 flowName)
183 return
184
185 components = stateListToDict(flows[flowName].get('components'))
186 if componentName not in components:
187 self.warning('not polling %s%s:%s: no such component %s',
188 managerId, componentId, uiStateKey,
189 componentId)
190 return
191
192 state = components[componentName]
193
194 def gotUIState(uiState):
195 if not uiState.hasKey(uiStateKey):
196 self.warning('while polling %s%s:%s: uiState has no '
197 'key %s', managerId, componentId,
198 uiStateKey, uiStateKey)
199 else:
200 try:
201 value = '%d:%s' % (int(time.time()),
202 uiState.get(uiStateKey))
203 self.log("polled %s%s:%s, updating ds %s = %s",
204 managerId, componentId, uiStateKey,
205 dsName, value)
206 rrdtool.update(rrdFile, "-t", dsName, value)
207 except rrdtool.error, e:
208 self.warning('error updating rrd file %s for '
209 '%s%s:%s', rrdFile, managerId,
210 componentId, uiStateKey)
211 self.debug('error reason: %s',
212 log.getExceptionMessage(e))
213
214 def errback(failure):
215 self.warning('not polling %s%s:%s: failed to get ui '
216 'state')
217 self.debug('reason: %s', log.getFailureMessage(failure))
218
219 d = admin.componentCallRemote(state, 'getUIState')
220 d.addCallbacks(gotUIState, errback)
221
| Trees | Indices | Help |
|---|
| Generated by Epydoc 3.0.1 on Fri Sep 24 12:51:01 2010 | http://epydoc.sourceforge.net |