summary refs log tree commit diff
path: root/synapse/metrics/metric.py
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/metrics/metric.py')
-rw-r--r--synapse/metrics/metric.py43
1 files changed, 37 insertions, 6 deletions
diff --git a/synapse/metrics/metric.py b/synapse/metrics/metric.py
index f5a98763cc..00b149f6f6 100644
--- a/synapse/metrics/metric.py
+++ b/synapse/metrics/metric.py
@@ -14,16 +14,28 @@
 # limitations under the License.
 
 
-class CounterMetric(object):
+class BaseMetric(object):
 
     def __init__(self, name, keys=[]):
         self.name = name
         self.keys = keys # OK not to clone as we never write it
 
+    def _render_key(self, values):
+        # TODO: some kind of value escape
+        return ",".join(["%s=%s" % kv for kv in zip(self.keys, values)])
+
+
+class CounterMetric(BaseMetric):
+    """The simplest kind of metric; one that stores a monotonically-increasing
+    integer that counts events."""
+
+    def __init__(self, *args, **kwargs):
+        super(CounterMetric, self).__init__(*args, **kwargs)
+
         self.counts = {}
 
         # Scalar metrics are never empty
-        if not len(keys):
+        if not len(self.keys):
             self.counts[()] = 0
 
     def inc(self, *values):
@@ -42,13 +54,32 @@ class CounterMetric(object):
     def fetch(self):
         return dict(self.counts)
 
-    def _render_key(self, values):
-        # TODO: some kind of value escape
-        return ",".join(["%s=%s" % kv for kv in zip(self.keys, values)])
-
     def render(self):
         if not len(self.keys):
             return ["%s %d" % (self.name, self.counts[()])]
 
         return ["%s{%s} %d" % (self.name, self._render_key(k), self.counts[k])
                 for k in sorted(self.counts.keys())]
+
+
+class CacheCounterMetric(object):
+    """A combination of two CounterMetrics, one to count cache hits and one to
+    count misses.
+
+    This metric generates standard metric name pairs, so that monitoring rules
+    can easily be applied to measure hit ratio."""
+
+    def __init__(self, name, keys=[]):
+        self.name = name
+
+        self.hits   = CounterMetric(name + ":hits",   keys=keys)
+        self.misses = CounterMetric(name + ":misses", keys=keys)
+
+    def inc_hits(self, *values):
+        self.hits.inc(*values)
+
+    def inc_misses(self, *values):
+        self.misses.inc(*values)
+
+    def render(self):
+        return self.hits.render() + self.misses.render()