Package Products :: Package ZenModel :: Module RRDView
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenModel.RRDView

  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 or (at your 
  8  # option) any later version as published by the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  import time 
 15   
 16  import logging 
 17  log = logging.getLogger("zen.RRDView") 
 18   
 19  from Acquisition import aq_chain 
 20   
 21  from Products.ZenRRD.RRDUtil import convertToRRDTime 
 22  from Products.ZenUtils import Map 
 23  from Products.ZenWidgets import messaging 
 24   
 25  from Products.ZenModel.ConfigurationError import ConfigurationError 
 26   
 27  CACHE_TIME = 60. 
 28   
 29  _cache = Map.Locked(Map.Timed({}, CACHE_TIME)) 
 30   
31 -def GetRRDPath(deviceOrComponent):
32 d = deviceOrComponent.device() 33 if not d: 34 return "Devices/" + deviceOrComponent.id 35 skip = len(d.getPrimaryPath()) - 1 36 return 'Devices/' + '/'.join(deviceOrComponent.getPrimaryPath()[skip:])
37 38
39 -class RRDViewError(Exception): pass
40 41
42 -class RRDView(object):
43 """ 44 Mixin to provide hooks to RRD management functions 45 """ 46
47 - def getGraphDefUrl(self, graph, drange=None, template=None):
48 """resolve template and graph names to objects 49 and pass to graph performance""" 50 if not drange: drange = self.defaultDateRange 51 templates = self.getRRDTemplates() 52 if template: 53 templates = [template] 54 if isinstance(graph, basestring): 55 for t in templates: 56 if hasattr(t.graphDefs, graph): 57 template = t 58 graph = getattr(t.graphDefs, graph) 59 break 60 targetpath = self.rrdPath() 61 objpaq = self.primaryAq() 62 perfServer = objpaq.device().getPerformanceServer() 63 if perfServer: 64 return perfServer.performanceGraphUrl(objpaq, targetpath, 65 template, graph, drange)
66
67 - def cacheRRDValue(self, dsname, default = "Unknown"):
68 "read an RRDValue with and cache it" 69 filename = self.getRRDFileName(dsname) 70 value = None 71 try: 72 value = _cache[filename] 73 if value is None: 74 return default 75 except KeyError: 76 pass 77 try: 78 value = self.getRRDValue(dsname) 79 except Exception: 80 log.error('Unable to cache value for %s', dsname) 81 _cache[filename] = value 82 if value is None: 83 return default 84 return value
85 86
87 - def getRRDValue(self, dsname, start=None, end=None, function="LAST", 88 format="%.2lf", extraRpn=""):
89 """Return a single rrd value from its file using function. 90 """ 91 dsnames = (dsname,) 92 results = self.getRRDValues( 93 dsnames, start, end, function, format, extraRpn) 94 if results and dsname in results: 95 return results[dsname]
96 97
98 - def getRRDDataPoints(self):
99 result = [] 100 for t in self.getRRDTemplates(): 101 result += t.getRRDDataPoints() 102 return result
103 104
105 - def getRRDDataPoint(self, dpName):
106 result = None 107 for t in self.getRRDTemplates(): 108 for dp in t.getRRDDataPoints(): 109 if dp.name() == dpName: 110 result = dp 111 break 112 return result
113 114
115 - def fetchRRDValues(self, dpnames, cf, resolution, start, end=""):
116 paths = [] 117 for dpname in dpnames: 118 paths.append(self.getRRDFileName(dpname)) 119 return self.device().getPerformanceServer().fetchValues(paths, 120 cf, resolution, start, end)
121 122
123 - def fetchRRDValue(self, dpname, cf, resolution, start, end=""):
124 r = self.fetchRRDValues([dpname,], cf, resolution, start, end=end) 125 if r is not None: 126 return r[0] 127 return None
128 129
130 - def getRRDValues(self, dsnames, start=None, end=None, function="LAST", 131 format="%.2lf", extraRpn=""):
132 """ 133 Return a dict of key value pairs where dsnames are the keys. 134 """ 135 try: 136 if not start: 137 start = time.time() - self.defaultDateRange 138 gopts = [] 139 names = list(dsnames[:]) 140 for dsname in dsnames: 141 for dp in self.getRRDDataPoints(): 142 if dp.name().find(dsname) > -1: 143 break 144 else: 145 names.remove(dsname) 146 continue 147 filename = self.getRRDFileName(dp.name()) 148 rpn = str(dp.rpn) 149 if rpn: 150 rpn = "," + rpn 151 if extraRpn: 152 rpn = rpn + "," + extraRpn 153 154 gopts.append("DEF:%s_r=%s:ds0:AVERAGE" % (dsname,filename)) 155 gopts.append("CDEF:%s_c=%s_r%s" % (dsname,dsname,rpn)) 156 gopts.append("VDEF:%s=%s_c,%s" % (dsname,dsname,function)) 157 gopts.append("PRINT:%s:%s" % (dsname, format)) 158 gopts.append("--start=%s" % convertToRRDTime(start)) 159 if end: 160 gopts.append("--end=%s" % convertToRRDTime(end)) 161 if not names: 162 return {} 163 perfServer = self.device().getPerformanceServer() 164 vals = [] 165 if perfServer: 166 vals = perfServer.performanceCustomSummary(gopts) 167 if vals is None: 168 vals = [None] * len(dsnames) 169 def cvt(val): 170 if val is None or val.lower() == "nan": 171 return None 172 return float(val)
173 return dict(zip(names, map(cvt, vals))) 174 except Exception, ex: 175 log.exception(ex)
176 177 178
179 - def getRRDSum(self, points, start=None, end=None, function="LAST"):
180 "Return a some of listed datapoints." 181 182 try: 183 if not start: 184 start = time.time() - self.defaultDateRange 185 if not end: 186 end = time.time() 187 gopts = [] 188 for name in points: 189 for dp in self.getRRDDataPoints(): 190 if dp.name().find(name) > -1: 191 break 192 else: 193 raise RRDViewError("Unable to find data point %s" % name) 194 filename = self.getRRDFileName(dp.name()) 195 rpn = str(dp.rpn) 196 if rpn: 197 rpn = "," + rpn 198 gopts.append("DEF:%s_r=%s:ds0:AVERAGE" % (name, filename)) 199 gopts.append("CDEF:%s=%s_r%s" % (name, name, rpn)) 200 gopts.append("CDEF:sum=%s%s" % (','.join(points), 201 ',+'*(len(points)-1))) 202 gopts.append("VDEF:agg=sum,%s" % function) 203 gopts.append("PRINT:agg:%.2lf") 204 gopts.append("--start=%d" % start) 205 gopts.append("--end=%d" % end) 206 perfServer = self.device().getPerformanceServer() 207 if perfServer: 208 vals = perfServer.performanceCustomSummary(gopts) 209 if vals is None: 210 return None 211 return float(vals[0]) 212 except Exception, ex: 213 log.exception(ex)
214 215
216 - def getDefaultGraphDefs(self, drange=None):
217 """get the default graph list for this object""" 218 graphs = [] 219 for template in self.getRRDTemplates(): 220 for g in template.getGraphDefs(): 221 graph = {} 222 graph['title'] = g.getId() 223 try: 224 graph['url'] = self.getGraphDefUrl(g, drange, template) 225 graphs.append(graph) 226 except ConfigurationError: 227 pass 228 return graphs
229 230
231 - def getGraphDef(self, graphId):
232 ''' Fetch a graph by id. if not found return None 233 ''' 234 for t in self.getRRDTemplates(): 235 for g in t.getGraphDefs(): 236 if g.id == graphId: 237 return g 238 return None
239 240
241 - def getRRDTemplateName(self):
242 """Return the target type name of this component. By default meta_type. 243 Override to create custom type selection. 244 """ 245 return self.meta_type
246 247
248 - def getRRDFileName(self, dsname):
249 """Look up an rrd file based on its data point name""" 250 names = [p.name() for p in self.getRRDDataPoints() 251 if p.name().endswith(dsname)] 252 if names: 253 return '%s/%s.rrd' % (self.rrdPath(), names[0]) 254 else: 255 return '%s/%s.rrd' % (self.rrdPath(), dsname)
256 257
258 - def getRRDNames(self):
259 return []
260
261 - def getRRDPaths(self):
262 return map(self.getRRDFileName, self.getRRDNames())
263
264 - def snmpIgnore(self):
265 """Should this component be monitored for performance using snmp. 266 """ 267 return False
268
269 - def getRRDTemplates(self):
270 default = self.getRRDTemplateByName(self.getRRDTemplateName()) 271 if not default: 272 return [] 273 return [default]
274
275 - def getRRDTemplate(self):
276 try: 277 return self.getRRDTemplates()[0] 278 except IndexError: 279 return None
280
281 - def getRRDTemplateByName(self, name):
282 "Return the template of the given name." 283 try: 284 return self._getOb(name) 285 except AttributeError: 286 pass 287 for obj in aq_chain(self): 288 try: 289 return obj.rrdTemplates._getOb(name) 290 except AttributeError: 291 pass 292 return None
293 294
295 - def getThresholds(self, templ):
296 """Return a dictionary where keys are dsnames and values are thresholds. 297 """ 298 result = {} 299 for thresh in templ.thresholds(): 300 if not thresh.enabled: continue 301 for dsname in thresh.dsnames: 302 threshdef = result.setdefault(dsname, []) 303 threshdef.append(thresh.getConfig(self)) 304 return result
305 306
307 - def rrdPath(self):
308 return GetRRDPath(self)
309 310
311 - def fullRRDPath(self):
312 from PerformanceConf import performancePath 313 return performancePath(self.rrdPath())
314
315 - def getRRDContextData(self, context):
316 return context
317
318 - def getThresholdInstances(self, dsType):
319 from Products.ZenEvents.Exceptions import pythonThresholdException 320 result = [] 321 for template in self.getRRDTemplates(): 322 # if the template refers to a data source name of the right type 323 # include it 324 names = [] 325 for ds in template.getRRDDataSources(dsType): 326 for dp in ds.datapoints(): 327 names.append(dp.name()) 328 for threshold in template.thresholds(): 329 if not threshold.enabled: continue 330 for ds in threshold.dsnames: 331 if ds in names: 332 try: 333 thresh = threshold.createThresholdInstance(self) 334 result.append(thresh) 335 except pythonThresholdException, ex: 336 log.warn(ex) 337 zem = self.primaryAq().getEventManager() 338 import socket 339 device = socket.gethostname() 340 path = template.absolute_url_path() 341 msg = \ 342 "The threshold %s in template %s has caused an exception." % (threshold.id, path) 343 evt = dict(summary=str(ex), severity=3, 344 component='zenhub', message=msg, 345 dedupid='zenhub|' + str(ex), 346 template=path, 347 threshold=threshold.id, 348 device=device, eventClass="/Status/Update",) 349 zem.sendEvent(evt) 350 break 351 return result
352 353
354 - def makeLocalRRDTemplate(self, templateName=None, REQUEST=None):
355 """Make a local copy of our RRDTemplate if one doesn't exist. 356 """ 357 if templateName is None: templateName = self.getRRDTemplateName() 358 if not self.isLocalName(templateName): 359 ct = self.getRRDTemplateByName(templateName)._getCopy(self) 360 ct.id = templateName 361 self._setObject(ct.id, ct) 362 if REQUEST: 363 messaging.IMessageSender(self).sendToBrowser( 364 'Template Created', 365 'Local copy "%s" created.' % templateName 366 ) 367 return self.callZenScreen(REQUEST)
368 369
370 - def removeLocalRRDTemplate(self, templateName=None, REQUEST=None):
371 """Make a local delete of our RRDTemplate if one doesn't exist. 372 """ 373 if templateName is None: templateName = self.getRRDTemplateName() 374 if self.isLocalName(templateName): 375 self._delObject(templateName) 376 if REQUEST: 377 messaging.IMessageSender(self).sendToBrowser( 378 'Template Removed', 379 'Local copy "%s" removed.' % templateName 380 ) 381 return self.callZenScreen(REQUEST)
382 383
384 -def updateCache(filenameValues):
385 _cache.update(dict(filenameValues))
386