| Trees | Indices | Help |
|
|---|
|
|
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 import time
12
13 import logging
14 log = logging.getLogger("zen.RRDView")
15
16 from Acquisition import aq_chain
17
18 from Products.ZenRRD.RRDUtil import convertToRRDTime
19 from Products.ZenUtils import Map
20 from Products.ZenWidgets import messaging
21
22 from Products.ZenModel.ConfigurationError import ConfigurationError
23
24 CACHE_TIME = 60.
25
26 _cache = Map.Locked(Map.Timed({}, CACHE_TIME))
27
29 d = deviceOrComponent.device()
30 if not d:
31 return "Devices/" + deviceOrComponent.id
32 skip = len(d.getPrimaryPath()) - 1
33 return 'Devices/' + '/'.join(deviceOrComponent.getPrimaryPath()[skip:])
34
35
37
38
40 """
41 Mixin to provide hooks to RRD management functions
42 """
43
45 """resolve template and graph names to objects
46 and pass to graph performance"""
47 if not drange: drange = self.defaultDateRange
48 templates = self.getRRDTemplates()
49 if template:
50 templates = [template]
51 if isinstance(graph, basestring):
52 for t in templates:
53 if hasattr(t.graphDefs, graph):
54 template = t
55 graph = getattr(t.graphDefs, graph)
56 break
57 targetpath = self.rrdPath()
58 objpaq = self.primaryAq()
59 perfServer = objpaq.device().getPerformanceServer()
60 if perfServer:
61 return perfServer.performanceGraphUrl(objpaq, targetpath,
62 template, graph, drange)
63
65 """
66 Cache RRD values for up to CACHE_TIME seconds.
67 """
68 # Notes:
69 # * _cache takes care of the time-limited-offer bits
70 # * rrdcached does cache results, but the first query
71 # could potentially cause a flush()
72 # * Remote collectors need this call to prevent extra
73 # calls across the network
74 filename = self.getRRDFileName(dsname)
75 try:
76 value = _cache[filename]
77 except KeyError:
78 try:
79 # Grab rrdcached value locally or from network
80 value = self.getRRDValue(dsname)
81 except Exception, ex:
82 # Generally a remote collector issue
83 # We'll cache this for a minute and then try again
84 value = None
85 log.error('Unable to get RRD value for %s: %s', dsname, ex)
86 _cache[filename] = value
87
88 return value if value is not None else default
89
90
91 - def getRRDValue(self, dsname, start=None, end=None, function="LAST",
92 format="%.2lf", extraRpn="", cf="AVERAGE"):
93 """Return a single rrd value from its file using function.
94 """
95 dsnames = (dsname,)
96 results = self.getRRDValues(
97 dsnames, start, end, function, format, extraRpn, cf=cf)
98 if results and dsname in results:
99 return results[dsname]
100
105
108
112
114 paths = [self.getRRDFileName(dpname) for dpname in dpnames]
115 return self.device().getPerformanceServer().fetchValues(paths,
116 cf, resolution, start, end)
117
118
120 r = self.fetchRRDValues([dpname,], cf, resolution, start, end=end)
121 if r:
122 return r[0]
123 return None
124
125
126 - def getRRDValues(self, dsnames, start=None, end=None, function="LAST",
127 format="%.2lf", extraRpn="", cf="AVERAGE"):
128 """
129 Return a dict of key value pairs where dsnames are the keys.
130 """
131 try:
132 if not start:
133 start = time.time() - self.defaultDateRange
134 gopts = []
135 # must copy dsnames into mutable list
136 names = list(dsnames)
137 for dsname in dsnames:
138 dp = next((d for d in self._getRRDDataPointsGen()
139 if dsname in d.name()), None)
140 if dp is None:
141 names.remove(dsname)
142 continue
143 filename = self.getRRDFileName(dp.name())
144 rpn = str(dp.rpn)
145 if rpn:
146 rpn = "," + rpn
147 if extraRpn:
148 rpn = rpn + "," + extraRpn
149
150 gopts.append("DEF:%s_r=%s:ds0:%s" % (dsname,filename,cf))
151 gopts.append("CDEF:%s_c=%s_r%s" % (dsname,dsname,rpn))
152 gopts.append("VDEF:%s=%s_c,%s" % (dsname,dsname,function))
153 gopts.append("PRINT:%s:%s" % (dsname, format))
154 gopts.append("--start=%s" % convertToRRDTime(start))
155 if end:
156 gopts.append("--end=%s" % convertToRRDTime(end))
157 if not names:
158 return {}
159 perfServer = self.device().getPerformanceServer()
160 vals = []
161 if perfServer:
162 vals = perfServer.performanceCustomSummary(gopts)
163 if vals is None:
164 vals = [None] * len(dsnames)
165 def cvt(val):
166 if val is None or val.lower() == "nan":
167 return None
168 return float(val)
169 return dict(zip(names, map(cvt, vals)))
170 except Exception, ex:
171 log.exception("Unable to collect RRD Values for %s" % self.getPrimaryId())
172
173
174
176 "Return a some of listed datapoints."
177
178 try:
179 if not start:
180 start = time.time() - self.defaultDateRange
181 if not end:
182 end = time.time()
183 gopts = []
184 for name in points:
185 dp = next((dp_ for dp_ in self._getRRDDataPointsGen()
186 if name in dp_.name()), None)
187 if dp is None:
188 raise RRDViewError("Unable to find data point %s" % name)
189
190 filename = self.getRRDFileName(dp.name())
191 rpn = str(dp.rpn)
192 if rpn:
193 rpn = "," + rpn
194 gopts.append("DEF:%s_r=%s:ds0:AVERAGE" % (name, filename))
195 gopts.append("CDEF:%s=%s_r%s" % (name, name, rpn))
196 gopts.append("CDEF:sum=%s%s" % (','.join(points),
197 ',+'*(len(points)-1)))
198 gopts.append("VDEF:agg=sum,%s" % function)
199 gopts.append("PRINT:agg:%.2lf")
200 gopts.append("--start=%d" % start)
201 gopts.append("--end=%d" % end)
202 perfServer = self.device().getPerformanceServer()
203 if perfServer:
204 vals = perfServer.performanceCustomSummary(gopts)
205 if vals is None:
206 return None
207 return float(vals[0])
208 except Exception, ex:
209 log.exception(ex)
210
211
213 """get the default graph list for this object"""
214 graphs = []
215 for template in self.getRRDTemplates():
216 for g in template.getGraphDefs():
217 graph = {}
218 graph['title'] = g.getId()
219 try:
220 graph['url'] = self.getGraphDefUrl(g, drange, template)
221 graphs.append(graph)
222 except ConfigurationError:
223 pass
224 return graphs
225
226
228 ''' Fetch a graph by id. if not found return None
229 '''
230 return next((g for t in self.getRRDTemplates()
231 for g in t.getGraphDefs()
232 if g.id == graphId),
233 None)
234
236 """Return the target type name of this component. By default meta_type.
237 Override to create custom type selection.
238 """
239 return self.meta_type
240
241
243 """Look up an rrd file based on its data point name"""
244 nm = next((p.name() for p in self._getRRDDataPointsGen()
245 if p.name().endswith(dsname)), dsname)
246 return '%s/%s.rrd' % (self.rrdPath(), nm)
247
248
251
254
259
261 default = self.getRRDTemplateByName(self.getRRDTemplateName())
262 if not default:
263 return []
264 return [default]
265
271
273 "Return the template of the given name."
274 try:
275 return self._getOb(name)
276 except AttributeError:
277 pass
278 for obj in aq_chain(self):
279 try:
280 return obj.rrdTemplates._getOb(name)
281 except AttributeError:
282 pass
283 return None
284
285
287 """Return a dictionary where keys are dsnames and values are thresholds.
288 """
289 result = {}
290 for thresh in templ.thresholds():
291 if not thresh.enabled: continue
292 for dsname in thresh.dsnames:
293 threshdef = result.setdefault(dsname, [])
294 threshdef.append(thresh.getConfig(self))
295 return result
296
298 return GetRRDPath(self)
299
300
304
306 return context
307
309 from Products.ZenEvents.Exceptions import pythonThresholdException
310 result = []
311 for template in self.getRRDTemplates():
312 # if the template refers to a data source name of the right type
313 # include it
314 names = set(dp.name() for ds in template.getRRDDataSources(dsType)
315 for dp in ds.datapoints())
316 for threshold in template.thresholds():
317 if not threshold.enabled: continue
318 for ds in threshold.dsnames:
319 if ds in names:
320 try:
321 thresh = threshold.createThresholdInstance(self)
322 result.append(thresh)
323 except pythonThresholdException, ex:
324 log.warn(ex)
325 zem = self.primaryAq().getEventManager()
326 import socket
327 device = socket.gethostname()
328 path = template.absolute_url_path()
329 msg = \
330 "The threshold %s in template %s has caused an exception." % (threshold.id, path)
331 evt = dict(summary=str(ex), severity=3,
332 component='zenhub', message=msg,
333 dedupid='zenhub|' + str(ex),
334 template=path,
335 threshold=threshold.id,
336 device=device, eventClass="/Status/Update",)
337 zem.sendEvent(evt)
338 break
339 return result
340
341
343 """Make a local copy of our RRDTemplate if one doesn't exist.
344 """
345 if templateName is None: templateName = self.getRRDTemplateName()
346 if not self.isLocalName(templateName):
347 ct = self.getRRDTemplateByName(templateName)._getCopy(self)
348 ct.id = templateName
349 self._setObject(ct.id, ct)
350 if REQUEST:
351 messaging.IMessageSender(self).sendToBrowser(
352 'Template Created',
353 'Local copy "%s" created.' % templateName
354 )
355 return self.callZenScreen(REQUEST)
356
357
359 """Make a local delete of our RRDTemplate if one doesn't exist.
360 """
361 if templateName is None: templateName = self.getRRDTemplateName()
362 if self.isLocalName(templateName):
363 self._delObject(templateName)
364 if REQUEST:
365 messaging.IMessageSender(self).sendToBrowser(
366 'Template Removed',
367 'Local copy "%s" removed.' % templateName
368 )
369 return self.callZenScreen(REQUEST)
370
371
374
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1.1812 on Mon Jul 30 17:11:42 2012 | http://epydoc.sourceforge.net |