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