def save_sample(self, metric, value, timestamp=None, dimensions=None, hostname=None, device_name=None): """Save a simple sample, evict old values if needed. """ if timestamp is None: timestamp = time.time() if metric not in self._sample_store: raise exceptions.CheckException("Saving a sample for an undefined metric: %s" % metric) try: value = util.cast_metric_val(value) except ValueError as ve: raise exceptions.NaN(ve) # Data eviction rules key = (tuple(sorted(dimensions.items())), device_name) if self.is_gauge(metric): self._sample_store[metric][key] = ((timestamp, value, hostname, device_name), ) elif self.is_counter(metric): if self._sample_store[metric].get(key) is None: self._sample_store[metric][key] = [(timestamp, value, hostname, device_name)] else: self._sample_store[metric][key] = self._sample_store[metric][key][-1:] + \ [(timestamp, value, hostname, device_name)] else: raise exceptions.CheckException("%s must be either gauge or counter, skipping sample at %s" % (metric, time.ctime(timestamp))) if self.is_gauge(metric): # store[metric][dimensions] = (ts, val) - only 1 value allowed assert len(self._sample_store[metric][key]) == 1, self._sample_store[metric] elif self.is_counter(metric): assert len(self._sample_store[metric][key]) in (1, 2), self._sample_store[metric]
def _rate(cls, sample1, sample2): """Simple rate. """ try: rate_interval = sample2[0] - sample1[0] if rate_interval == 0: raise exceptions.Infinity() delta = sample2[1] - sample1[1] if delta < 0: raise exceptions.UnknownValue() return (sample2[0], delta / rate_interval, sample2[2], sample2[3]) except exceptions.Infinity: raise except exceptions.UnknownValue: raise except Exception as e: raise exceptions.NaN(e)