Browse files

add derive instrument

  • Loading branch information...
1 parent ae17368 commit cbde37818da31051fa02131875054ef60d32774d @cyberdelia committed Oct 23, 2012
View
7 docs/instruments.rst
@@ -17,6 +17,13 @@ Counters
.. automodule:: metrology.instruments.counter
:members:
+Derive
+======
+
+.. automodule:: metrology.instruments.derive
+ :members:
+
+
Meters
======
View
4 metrology/__init__.py
@@ -11,6 +11,10 @@ def counter(cls, name):
return registry.counter(name)
@classmethod
+ def derive(cls, name):
+ return registry.derive(name)
+
+ @classmethod
def meter(cls, name):
return registry.meter(name)
View
1 metrology/instruments/__init__.py
@@ -1,5 +1,6 @@
# -*- flake8: noqa -*-
from metrology.instruments.counter import Counter
+from metrology.instruments.derive import Derive
from metrology.instruments.gauge import Gauge
from metrology.instruments.histogram import Histogram, HistogramUniform, HistogramExponentiallyDecaying
from metrology.instruments.meter import Meter
View
28 metrology/instruments/derive.py
@@ -0,0 +1,28 @@
+from atomic import Atomic
+
+from metrology.instruments.meter import Meter
+from metrology.stats import EWMA
+
+
+class Derive(Meter):
+ """
+ A derive is like a meter but accepts an absolute counter as input.
+
+ derive = Metrology.derive('network.io')
+ derive.mark()
+ derive.count
+
+ """
+ def __init__(self, average_class=EWMA):
+ self.last = Atomic(0)
+ super(Derive, self).__init__(average_class)
+
+ def mark(self, value=1):
+ """Record an event with the derive.
+
+ :param value: counter value to record
+ """
+ last = self.last.get_and_set(value)
+ if last <= value:
+ value = value - last
+ super(Derive, self).mark(value)
View
5 metrology/registry.py
@@ -3,7 +3,7 @@
from threading import RLock
from metrology.exceptions import RegistryException
-from metrology.instruments import Counter, Profiler, Meter, Timer, UtilizationTimer, HistogramUniform
+from metrology.instruments import Counter, Derive, Profiler, Meter, Timer, UtilizationTimer, HistogramUniform
class Registry(object):
@@ -41,6 +41,9 @@ def histogram(self, name, klass=None):
klass = HistogramUniform
return self.add_or_get(name, klass)
+ def derive(self, name):
+ return self.add_or_get(name, Derive)
+
def profiler(self, name):
return self.add_or_get(name, Profiler)
View
28 tests/instruments/test_derive.py
@@ -0,0 +1,28 @@
+from unittest import TestCase
+
+from metrology.instruments.derive import Derive
+
+
+class DeriveTest(TestCase):
+ def setUp(self):
+ self.derive = Derive()
+
+ def test_derive(self):
+ self.derive.mark()
+ self.assertEqual(1, self.derive.count)
+
+ def test_blank_derive(self):
+ self.assertEqual(0, self.derive.count)
+ self.assertEqual(0.0, self.derive.mean_rate)
+
+ def test_derive_value(self):
+ self.derive.mark(3)
+ self.assertEqual(3, self.derive.count)
+
+ def test_one_minute_rate(self):
+ self.derive.mark(1000)
+ self.derive.tick()
+ self.assertEqual(200, self.derive.one_minute_rate)
+
+ def tearDown(self):
+ self.derive.stop()

0 comments on commit cbde378

Please sign in to comment.