def evaluateDataSourceExpression(self, context, propName, readablePropName): """ Return back a sane value from evaluation of an expression. @paramter context: device or component object @type context: device or component object @paramter propName: name of the threshold property to evaluate @type propName: string @paramter readablePropName: property name for displaying in error messages @type readablePropName: string @returns: numeric @rtype: numeric """ value = getattr(self, propName, None) if value: try: express = "python:%s" % value evaluated = talesEval(express, context) value = evaluated except: msg= "User-supplied Python expression (%s) for %s caused error: %s" % ( value, readablePropName, self.dsnames) log.error(msg) raise pythonThresholdException(msg) value = None return nanToNone(value)
def getGraphValues(self, relatedGps, context): """ Returns the values that we want to include for the visualization of this threshold. For a minmax we simply display lines representing the minval and maxval. """ minval = self.minimum if minval is None or minval == '': minval = NaN maxval = self.maximum if maxval is None or maxval == '': maxval = NaN if not self.dataPointNames: return [] gp = relatedGps[self.dataPointNames[0]] # Attempt any RPN expressions rpn = getattr(gp, 'rpn', None) if rpn: try: rpn = talesEvalStr(rpn, context) except Exception as e: log.exception(e) self.raiseRPNExc() return [] try: if minval is not NaN: minval = rpneval(minval, rpn) except Exception: minval = 0 self.raiseRPNExc() try: if maxval is not NaN: maxval = rpneval(maxval, rpn) except Exception: maxval = 0 self.raiseRPNExc() minval = nanToNone(minval) maxval = nanToNone(maxval) return [minval, maxval]
def getMaxval(self, context): """Build the max value for this threshold. """ maxval = None if self.maxval: try: express = "python:%s" % self.maxval maxval = talesEval(express, context) except: msg = ("User-supplied Python expression (%s) for " "maximum value caused error: %s") % (self.maxval, self.dsnames) log.error(msg) raise pythonThresholdException(msg) maxval = None return nanToNone(maxval)
def getGraphElements(self, template, context, gopts, namespace, color, legend, relatedGps): """Produce a visual indication on the graph of where the threshold applies.""" unused(template, namespace) if not color.startswith('#'): color = '#%s' % color minval = self.minimum if minval is None or minval == '': minval = NaN maxval = self.maximum if maxval is None or maxval == '': maxval = NaN if not self.dataPointNames: return gopts gp = relatedGps[self.dataPointNames[0]] # Attempt any RPN expressions rpn = getattr(gp, 'rpn', None) if rpn: try: rpn = talesEvalStr(rpn, context) except: self.raiseRPNExc() return gopts try: minval = rpneval(minval, rpn) except: minval= 0 self.raiseRPNExc() try: maxval = rpneval(maxval, rpn) except: maxval= 0 self.raiseRPNExc() minstr = self.setPower(minval) maxstr = self.setPower(maxval) minval = nanToNone(minval) maxval = nanToNone(maxval) if legend: gopts.append( "HRULE:%s%s:%s\\j" % (minval or maxval, color, legend)) elif minval is not None and maxval is not None: if minval == maxval: gopts.append( "HRULE:%s%s:%s not equal to %s\\j" % (minval, color, self.getNames(relatedGps), minstr)) elif minval < maxval: gopts.append( "HRULE:%s%s:%s not within %s and %s\\j" % (minval, color, self.getNames(relatedGps), minstr, maxstr)) gopts.append("HRULE:%s%s" % (maxval, color)) elif minval > maxval: gopts.append( "HRULE:%s%s:%s between %s and %s\\j" % (minval, color, self.getNames(relatedGps), maxstr, minstr)) gopts.append("HRULE:%s%s" % (maxval, color)) elif minval is not None : gopts.append( "HRULE:%s%s:%s less than %s\\j" % (minval, color, self.getNames(relatedGps), minstr)) elif maxval is not None: gopts.append( "HRULE:%s%s:%s greater than %s\\j" % (maxval, color, self.getNames(relatedGps), maxstr)) return gopts
def getGraphElements(self, template, context, gopts, namespace, color, legend, relatedGps): """Produce a visual indication on the graph of where the threshold applies.""" unused(template, namespace) if not color.startswith('#'): color = '#%s' % color minval = self.minimum if minval is None: minval = NaN maxval = self.maximum if maxval is None: maxval = NaN if not self.dataPointNames: return gopts gp = relatedGps[self.dataPointNames[0]] # Attempt any RPN expressions rpn = getattr(gp, 'rpn', None) if rpn: try: rpn = talesEvalStr(rpn, context) except: self.raiseRPNExc() return gopts try: minval = rpneval(minval, rpn) except: minval= 0 self.raiseRPNExc() try: maxval = rpneval(maxval, rpn) except: maxval= 0 self.raiseRPNExc() minstr = self.setPower(minval) maxstr = self.setPower(maxval) minval = nanToNone(minval) maxval = nanToNone(maxval) if legend: gopts.append( "HRULE:%s%s:%s\\j" % (minval or maxval, color, legend)) elif minval is not None and maxval is not None: if minval == maxval: gopts.append( "HRULE:%s%s:%s not equal to %s\\j" % (minval, color, self.getNames(relatedGps), minstr)) elif minval < maxval: gopts.append( "HRULE:%s%s:%s not within %s and %s\\j" % (minval, color, self.getNames(relatedGps), minstr, maxstr)) gopts.append("HRULE:%s%s" % (maxval, color)) elif minval > maxval: gopts.append( "HRULE:%s%s:%s between %s and %s\\j" % (minval, color, self.getNames(relatedGps), maxstr, minstr)) gopts.append("HRULE:%s%s" % (maxval, color)) elif minval is not None : gopts.append( "HRULE:%s%s:%s less than %s\\j" % (minval, color, self.getNames(relatedGps), minstr)) elif maxval is not None: gopts.append( "HRULE:%s%s:%s greater than %s\\j" % (maxval, color, self.getNames(relatedGps), maxstr)) return gopts
class MinMaxThresholdInstance(MetricThresholdInstance): # Not strictly necessary, but helps when restoring instances from # pickle files that were not constructed with a count member. count = {} def __init__(self, id, context, dpNames, minval, maxval, eventClass, severity, escalateCount, eventFields={}): MetricThresholdInstance.__init__(self, id, context, dpNames, eventClass, severity) self.count = {} self.minimum = minval if minval != '' else None self.maximum = maxval if maxval != '' else None self.escalateCount = escalateCount self.eventFields = eventFields def countKey(self, dp): return ':'.join(self.context().key()) + ':' + dp def getCount(self, dp): countKey = self.countKey(dp) if not countKey in self.count: return None return self.count[countKey] def incrementCount(self, dp): countKey = self.countKey(dp) if not countKey in self.count: self.resetCount(dp) self.count[countKey] += 1 return self.count[countKey] def resetCount(self, dp): self.count[self.countKey(dp)] = 0 def checkRange(self, dp, value): 'Check the value for min/max thresholds' log.debug("Checking %s %s against min %s and max %s", dp, value, self.minimum, self.maximum) if value is None: return [] if isinstance(value, basestring): value = float(value) # Check the boundaries minbounds = self.minimum is None or value >= self.minimum maxbounds = self.maximum is None or value <= self.maximum outbounds = None not in (self.minimum, self.maximum) and \ self.minimum > self.maximum thresh = None how = None if outbounds: if not maxbounds and not minbounds: thresh = self.maximum how = 'violated' else: if not maxbounds: thresh = self.maximum how = 'exceeded' elif not minbounds: thresh = self.minimum how = 'not met' if thresh is not None: severity = self.severity count = self.incrementCount(dp) if self.escalateCount and count >= self.escalateCount: severity = min(severity + 1, 5) summary = 'threshold of %s %s: current value %f' % ( self.name(), how, float(value)) evtdict = self._create_event_dict(value, summary, severity, how) if self.escalateCount: evtdict['escalation_count'] = count return self.processEvent(evtdict) else: summary = 'threshold of %s restored: current value %f' % ( self.name(), value) self.resetCount(dp) return self.processClearEvent(self._create_event_dict(value, summary, Event.Clear)) def _create_event_dict(self, current, summary, severity, how=None): event_dict = dict(device=self.context().deviceName, summary=summary, eventKey=self.id, eventClass=self.eventClass, component=self.context().componentName, min=self.minimum, max=self.maximum, current=current, severity=severity) deviceUrl = getattr(self.context(), "deviceUrl", None) if deviceUrl is not None: event_dict["zenoss.device.url"] = deviceUrl devicePath = getattr(self.context(), "devicePath", None) if devicePath is not None: event_dict["zenoss.device.path"] = devicePath if how is not None: event_dict['how'] = how event_dict.update(self.eventFields) return event_dict def processEvent(self, evt): """ When a threshold condition is violated, pre-process it for (possibly) nicer formatting or more complicated logic. @paramater evt: event @type evt: dictionary @rtype: list of dictionaries """ return [evt] def processClearEvent(self, evt): """ When a threshold condition is restored, pre-process it for (possibly) nicer formatting or more complicated logic. @paramater evt: event @type evt: dictionary @rtype: list of dictionaries """ return [evt] def raiseRPNExc( self ): """ Raise an RPN exception, taking care to log all details. """ msg= "The following RPN exception is from user-supplied code." log.exception( msg ) raise rpnThresholdException(msg) def getGraphValues(self, relatedGps, context): """ Returns the values that we want to include for the visualization of this threshold. For a minmax we simply display lines representing the minval and maxval. """ minval = self.minimum if minval is None or minval == '': minval = NaN maxval = self.maximum if maxval is None or maxval == '': maxval = NaN if not self.dataPointNames: return [] gp = relatedGps[self.dataPointNames[0]] # Attempt any RPN expressions rpn = getattr(gp, 'rpn', None) if rpn: try: rpn = talesEvalStr(rpn, context) except Exception, e: log.exception(e) self.raiseRPNExc() return [] try: if minval is not NaN: minval = rpneval(minval, rpn) except: minval= 0 self.raiseRPNExc() try: if maxval is not NaN: maxval = rpneval(maxval, rpn) except: maxval= 0 self.raiseRPNExc() minval = nanToNone(minval) maxval = nanToNone(maxval) return [minval, maxval]