diff --git a/synapse/metrics/metric.py b/synapse/metrics/metric.py
index 45d2752a20..12460c99c3 100644
--- a/synapse/metrics/metric.py
+++ b/synapse/metrics/metric.py
@@ -64,7 +64,7 @@ class CounterMetric(BaseMetric):
if self.is_scalar():
self.counts[()] = 0
- def inc(self, *values):
+ def inc_by(self, incr, *values):
if len(values) != self.dimension():
raise ValueError("Expected as many values to inc() as labels (%d)" %
(self.dimension())
@@ -73,9 +73,12 @@ class CounterMetric(BaseMetric):
# TODO: should assert that the tag values are all strings
if values not in self.counts:
- self.counts[values] = 1
+ self.counts[values] = incr
else:
- self.counts[values] += 1
+ self.counts[values] += incr
+
+ def inc(self, *values):
+ self.inc_by(1, *values)
def render_item(self, k):
return ["%s%s %d" % (self.name, self._render_key(k), self.counts[k])]
@@ -101,7 +104,7 @@ class CallbackMetric(BaseMetric):
for k in sorted(value.keys())]
-class DistributionMetric(CounterMetric):
+class DistributionMetric(object):
"""A combination of an event counter and an accumulator, which counts
both the number of events and accumulates the total value. Typically this
could be used to keep track of method-running times, or other distributions
@@ -110,28 +113,16 @@ class DistributionMetric(CounterMetric):
TODO(paul): Try to export some heatmap-style stats?
"""
- def __init__(self, *args, **kwargs):
- super(DistributionMetric, self).__init__(*args, **kwargs)
-
- self.totals = {}
-
- # Scalar metrics are never empty
- if self.is_scalar():
- self.totals[()] = 0
+ def __init__(self, name, *args, **kwargs):
+ self.counts = CounterMetric(name + ":count", **kwargs)
+ self.totals = CounterMetric(name + ":total", **kwargs)
def inc_by(self, inc, *values):
- self.inc(*values)
-
- if values not in self.totals:
- self.totals[values] = inc
- else:
- self.totals[values] += inc
+ self.counts.inc(*values)
+ self.totals.inc_by(inc, *values)
- def render_item(self, k):
- keystr = self._render_key(k)
-
- return ["%s:count%s %d" % (self.name, keystr, self.counts[k]),
- "%s:total%s %d" % (self.name, keystr, self.totals[k])]
+ def render(self):
+ return self.counts.render() + self.totals.render()
class CacheMetric(object):
diff --git a/tests/metrics/test_metric.py b/tests/metrics/test_metric.py
index 1ca3e45a26..6009014297 100644
--- a/tests/metrics/test_metric.py
+++ b/tests/metrics/test_metric.py
@@ -35,8 +35,7 @@ class CounterMetricTestCase(unittest.TestCase):
'scalar 1',
])
- counter.inc()
- counter.inc()
+ counter.inc_by(2)
self.assertEquals(counter.render(), [
'scalar 3'
@@ -125,8 +124,8 @@ class DistributionMetricTestCase(unittest.TestCase):
self.assertEquals(metric.render(), [
'queries:count{verb="INSERT"} 1',
- 'queries:total{verb="INSERT"} 800',
'queries:count{verb="SELECT"} 2',
+ 'queries:total{verb="INSERT"} 800',
'queries:total{verb="SELECT"} 500',
])
|