From 732f818f5a0586c08bd1515422905f0f4671ecfc Mon Sep 17 00:00:00 2001 From: Conor Branagan Date: Tue, 30 Oct 2012 17:41:09 -0400 Subject: [PATCH 1/2] clear old counter values on flush, keeping the last sample --- checks/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/checks/__init__.py b/checks/__init__.py index a0556732b6..c5a287b15a 100644 --- a/checks/__init__.py +++ b/checks/__init__.py @@ -213,7 +213,9 @@ def get_sample_with_timestamp(self, metric, tags=None, device_name=None): raise UnknownValue() elif self.is_counter(metric) and len(self._sample_store[metric][key]) >= 2: - return self._rate(self._sample_store[metric][key][-2], self._sample_store[metric][key][-1]) + res = self._rate(self._sample_store[metric][key][-2], self._sample_store[metric][key][-1]) + del self._sample_store[metric][key][:-1] + return res elif self.is_gauge(metric) and len(self._sample_store[metric][key]) >= 1: return self._sample_store[metric][key][-1] From 9304b3d07aa5102cf0f693213fb70b4ee5a32588 Mon Sep 17 00:00:00 2001 From: Conor Branagan Date: Tue, 30 Oct 2012 18:38:20 -0400 Subject: [PATCH 2/2] make expiration configurable so tests can pass --- checks/__init__.py | 23 ++++++++++++----------- tests/test_common.py | 16 ++++++++-------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/checks/__init__.py b/checks/__init__.py index c5a287b15a..b6dd9cb7a5 100644 --- a/checks/__init__.py +++ b/checks/__init__.py @@ -195,7 +195,7 @@ def _rate(cls, sample1, sample2): except Exception, e: raise NaN(e) - def get_sample_with_timestamp(self, metric, tags=None, device_name=None): + def get_sample_with_timestamp(self, metric, tags=None, device_name=None, expire=True): "Get (timestamp-epoch-style, value)" # Get the proper tags @@ -210,11 +210,12 @@ def get_sample_with_timestamp(self, metric, tags=None, device_name=None): # Not enough value to compute rate elif self.is_counter(metric) and len(self._sample_store[metric][key]) < 2: - raise UnknownValue() + raise UnknownValue() elif self.is_counter(metric) and len(self._sample_store[metric][key]) >= 2: res = self._rate(self._sample_store[metric][key][-2], self._sample_store[metric][key][-1]) - del self._sample_store[metric][key][:-1] + if expire: + del self._sample_store[metric][key][:-1] return res elif self.is_gauge(metric) and len(self._sample_store[metric][key]) >= 1: @@ -223,34 +224,34 @@ def get_sample_with_timestamp(self, metric, tags=None, device_name=None): else: raise UnknownValue() - def get_sample(self, metric, tags=None, device_name=None): + def get_sample(self, metric, tags=None, device_name=None, expire=True): "Return the last value for that metric" - x = self.get_sample_with_timestamp(metric, tags, device_name) + x = self.get_sample_with_timestamp(metric, tags, device_name, expire) assert type(x) == types.TupleType and len(x) == 4, x return x[1] - def get_samples_with_timestamps(self): + def get_samples_with_timestamps(self, expire=True): "Return all values {metric: (ts, value)} for non-tagged metrics" values = {} for m in self._sample_store: try: - values[m] = self.get_sample_with_timestamp(m) + values[m] = self.get_sample_with_timestamp(m, expire=expire) except: pass return values - def get_samples(self): + def get_samples(self, expire=True): "Return all values {metric: value} for non-tagged metrics" values = {} for m in self._sample_store: try: # Discard the timestamp - values[m] = self.get_sample_with_timestamp(m)[1] + values[m] = self.get_sample_with_timestamp(m, expire=expire)[1] except: pass return values - def get_metrics(self): + def get_metrics(self, expire=True): """Get all metrics, including the ones that are tagged. This is the preferred method to retrieve metrics @@ -263,7 +264,7 @@ def get_metrics(self): for key in self._sample_store[m]: tags, device_name = key try: - ts, val, hostname, device_name = self.get_sample_with_timestamp(m, tags, device_name) + ts, val, hostname, device_name = self.get_sample_with_timestamp(m, tags, device_name, expire) except UnknownValue: continue attributes = {} diff --git a/tests/test_common.py b/tests/test_common.py index 9e7fe144db..7ebcd02c8b 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -40,11 +40,11 @@ def testEdgeCases(self): def test_counter(self): self.c.save_sample("test-counter", 1.0, 1.0) - self.assertRaises(UnknownValue, self.c.get_sample, "test-counter") + self.assertRaises(UnknownValue, self.c.get_sample, "test-counter", expire=False) self.c.save_sample("test-counter", 2.0, 2.0) - self.assertEquals(self.c.get_sample("test-counter"), 1.0) - self.assertEquals(self.c.get_sample_with_timestamp("test-counter"), (2.0, 1.0, None, None)) - self.assertEquals(self.c.get_samples(), {"test-counter": 1.0}) + self.assertEquals(self.c.get_sample("test-counter", expire=False), 1.0) + self.assertEquals(self.c.get_sample_with_timestamp("test-counter", expire=False), (2.0, 1.0, None, None)) + self.assertEquals(self.c.get_samples(expire=False), {"test-counter": 1.0}) self.c.save_sample("test-counter", -2.0, 3.0) self.assertRaises(UnknownValue, self.c.get_sample_with_timestamp, "test-counter") @@ -76,10 +76,10 @@ def test_samples(self): self.c.save_sample("test-metric", 1.0, 0.0) # value, ts self.c.save_sample("test-counter", 1.0, 1.0) # value, ts self.c.save_sample("test-counter", 4.0, 2.0) # value, ts - assert "test-metric" in self.c.get_samples_with_timestamps(), self.c.get_samples_with_timestamps() - self.assertEquals(self.c.get_samples_with_timestamps()["test-metric"], (0.0, 1.0, None, None)) - assert "test-counter" in self.c.get_samples_with_timestamps(), self.c.get_samples_with_timestamps() - self.assertEquals(self.c.get_samples_with_timestamps()["test-counter"], (2.0, 3.0, None, None)) + assert "test-metric" in self.c.get_samples_with_timestamps(expire=False), self.c.get_samples_with_timestamps(expire=False) + self.assertEquals(self.c.get_samples_with_timestamps(expire=False)["test-metric"], (0.0, 1.0, None, None)) + assert "test-counter" in self.c.get_samples_with_timestamps(expire=False), self.c.get_samples_with_timestamps(expire=False) + self.assertEquals(self.c.get_samples_with_timestamps(expire=False)["test-counter"], (2.0, 3.0, None, None)) def test_name(self): self.assertEquals(self.c.normalize("metric"), "metric")