Rename TimerMetric to DistributionMetric; as it could count more than just time
This commit is contained in:
parent
642f725fd7
commit
f1fbe3e09f
|
@ -19,7 +19,9 @@ from __future__ import absolute_import
|
||||||
import logging
|
import logging
|
||||||
from resource import getrusage, getpagesize, RUSAGE_SELF
|
from resource import getrusage, getpagesize, RUSAGE_SELF
|
||||||
|
|
||||||
from .metric import CounterMetric, CallbackMetric, TimerMetric, CacheMetric
|
from .metric import (
|
||||||
|
CounterMetric, CallbackMetric, DistributionMetric, CacheMetric
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -59,8 +61,8 @@ class Metrics(object):
|
||||||
def register_callback(self, *args, **kwargs):
|
def register_callback(self, *args, **kwargs):
|
||||||
return self._register(CallbackMetric, *args, **kwargs)
|
return self._register(CallbackMetric, *args, **kwargs)
|
||||||
|
|
||||||
def register_timer(self, *args, **kwargs):
|
def register_distribution(self, *args, **kwargs):
|
||||||
return self._register(TimerMetric, *args, **kwargs)
|
return self._register(DistributionMetric, *args, **kwargs)
|
||||||
|
|
||||||
def register_cache(self, *args, **kwargs):
|
def register_cache(self, *args, **kwargs):
|
||||||
return self._register(CacheMetric, *args, **kwargs)
|
return self._register(CacheMetric, *args, **kwargs)
|
||||||
|
|
|
@ -101,35 +101,37 @@ class CallbackMetric(BaseMetric):
|
||||||
for k in sorted(value.keys())]
|
for k in sorted(value.keys())]
|
||||||
|
|
||||||
|
|
||||||
class TimerMetric(CounterMetric):
|
class DistributionMetric(CounterMetric):
|
||||||
"""A combination of an event counter and a time accumulator, which counts
|
"""A combination of an event counter and an accumulator, which counts
|
||||||
both the number of events and how long each one takes.
|
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
|
||||||
|
of values that occur in discrete occurances.
|
||||||
|
|
||||||
TODO(paul): Try to export some heatmap-style stats?
|
TODO(paul): Try to export some heatmap-style stats?
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(TimerMetric, self).__init__(*args, **kwargs)
|
super(DistributionMetric, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.times = {}
|
self.totals = {}
|
||||||
|
|
||||||
# Scalar metrics are never empty
|
# Scalar metrics are never empty
|
||||||
if self.is_scalar():
|
if self.is_scalar():
|
||||||
self.times[()] = 0
|
self.totals[()] = 0
|
||||||
|
|
||||||
def inc_time(self, msec, *values):
|
def inc_by(self, inc, *values):
|
||||||
self.inc(*values)
|
self.inc(*values)
|
||||||
|
|
||||||
if values not in self.times:
|
if values not in self.totals:
|
||||||
self.times[values] = msec
|
self.totals[values] = inc
|
||||||
else:
|
else:
|
||||||
self.times[values] += msec
|
self.totals[values] += inc
|
||||||
|
|
||||||
def render_item(self, k):
|
def render_item(self, k):
|
||||||
keystr = self._render_key(k)
|
keystr = self._render_key(k)
|
||||||
|
|
||||||
return ["%s:count%s %d" % (self.name, keystr, self.counts[k]),
|
return ["%s:count%s %d" % (self.name, keystr, self.counts[k]),
|
||||||
"%s:msec%s %d" % (self.name, keystr, self.times[k])]
|
"%s:total%s %d" % (self.name, keystr, self.totals[k])]
|
||||||
|
|
||||||
|
|
||||||
class CacheMetric(object):
|
class CacheMetric(object):
|
||||||
|
|
|
@ -38,9 +38,9 @@ transaction_logger = logging.getLogger("synapse.storage.txn")
|
||||||
|
|
||||||
metrics = synapse.metrics.get_metrics_for("synapse.storage")
|
metrics = synapse.metrics.get_metrics_for("synapse.storage")
|
||||||
|
|
||||||
sql_query_timer = metrics.register_timer("queries", labels=["verb"])
|
sql_query_timer = metrics.register_distribution("queries", labels=["verb"])
|
||||||
sql_txn_timer = metrics.register_timer("transactions", labels=["desc"])
|
sql_txn_timer = metrics.register_distribution("transactions", labels=["desc"])
|
||||||
sql_getevents_timer = metrics.register_timer("getEvents", labels=["desc"])
|
sql_getevents_timer = metrics.register_distribution("getEvents", labels=["desc"])
|
||||||
|
|
||||||
caches_by_name = {}
|
caches_by_name = {}
|
||||||
cache_counter = metrics.register_cache(
|
cache_counter = metrics.register_cache(
|
||||||
|
@ -143,7 +143,7 @@ class LoggingTransaction(object):
|
||||||
finally:
|
finally:
|
||||||
msecs = (time.time() * 1000) - start
|
msecs = (time.time() * 1000) - start
|
||||||
sql_logger.debug("[SQL time] {%s} %f", self.name, msecs)
|
sql_logger.debug("[SQL time] {%s} %f", self.name, msecs)
|
||||||
sql_query_timer.inc_time(msecs, sql.split()[0])
|
sql_query_timer.inc_by(msecs, sql.split()[0])
|
||||||
|
|
||||||
|
|
||||||
class PerformanceCounters(object):
|
class PerformanceCounters(object):
|
||||||
|
@ -268,7 +268,7 @@ class SQLBaseStore(object):
|
||||||
self._current_txn_total_time += end - start
|
self._current_txn_total_time += end - start
|
||||||
self._txn_perf_counters.update(desc, start, end)
|
self._txn_perf_counters.update(desc, start, end)
|
||||||
|
|
||||||
sql_txn_timer.inc_time(self._current_txn_total_time, desc)
|
sql_txn_timer.inc_by(self._current_txn_total_time, desc)
|
||||||
|
|
||||||
with PreserveLoggingContext():
|
with PreserveLoggingContext():
|
||||||
result = yield self._db_pool.runInteraction(
|
result = yield self._db_pool.runInteraction(
|
||||||
|
@ -672,7 +672,7 @@ class SQLBaseStore(object):
|
||||||
|
|
||||||
def update_counter(desc, last_time):
|
def update_counter(desc, last_time):
|
||||||
curr_time = self._get_event_counters.update(desc, last_time)
|
curr_time = self._get_event_counters.update(desc, last_time)
|
||||||
sql_getevents_timer.inc_time(curr_time - last_time, desc)
|
sql_getevents_timer.inc_by(curr_time - last_time, desc)
|
||||||
return curr_time
|
return curr_time
|
||||||
|
|
||||||
cache = self._get_event_cache.setdefault(event_id, {})
|
cache = self._get_event_cache.setdefault(event_id, {})
|
||||||
|
@ -727,7 +727,7 @@ class SQLBaseStore(object):
|
||||||
|
|
||||||
def update_counter(desc, last_time):
|
def update_counter(desc, last_time):
|
||||||
curr_time = self._get_event_counters.update(desc, last_time)
|
curr_time = self._get_event_counters.update(desc, last_time)
|
||||||
sql_getevents_timer.inc_time(curr_time - last_time, desc)
|
sql_getevents_timer.inc_by(curr_time - last_time, desc)
|
||||||
return curr_time
|
return curr_time
|
||||||
|
|
||||||
d = json.loads(js)
|
d = json.loads(js)
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
from tests import unittest
|
from tests import unittest
|
||||||
|
|
||||||
from synapse.metrics.metric import (
|
from synapse.metrics.metric import (
|
||||||
CounterMetric, CallbackMetric, TimerMetric, CacheMetric
|
CounterMetric, CallbackMetric, DistributionMetric, CacheMetric
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,37 +97,37 @@ class CallbackMetricTestCase(unittest.TestCase):
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
class TimerMetricTestCase(unittest.TestCase):
|
class DistributionMetricTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_scalar(self):
|
def test_scalar(self):
|
||||||
metric = TimerMetric("thing")
|
metric = DistributionMetric("thing")
|
||||||
|
|
||||||
self.assertEquals(metric.render(), [
|
self.assertEquals(metric.render(), [
|
||||||
'thing:count 0',
|
'thing:count 0',
|
||||||
'thing:msec 0',
|
'thing:total 0',
|
||||||
])
|
])
|
||||||
|
|
||||||
metric.inc_time(500)
|
metric.inc_by(500)
|
||||||
|
|
||||||
self.assertEquals(metric.render(), [
|
self.assertEquals(metric.render(), [
|
||||||
'thing:count 1',
|
'thing:count 1',
|
||||||
'thing:msec 500',
|
'thing:total 500',
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_vector(self):
|
def test_vector(self):
|
||||||
metric = TimerMetric("queries", labels=["verb"])
|
metric = DistributionMetric("queries", labels=["verb"])
|
||||||
|
|
||||||
self.assertEquals(metric.render(), [])
|
self.assertEquals(metric.render(), [])
|
||||||
|
|
||||||
metric.inc_time(300, "SELECT")
|
metric.inc_by(300, "SELECT")
|
||||||
metric.inc_time(200, "SELECT")
|
metric.inc_by(200, "SELECT")
|
||||||
metric.inc_time(800, "INSERT")
|
metric.inc_by(800, "INSERT")
|
||||||
|
|
||||||
self.assertEquals(metric.render(), [
|
self.assertEquals(metric.render(), [
|
||||||
'queries:count{verb="INSERT"} 1',
|
'queries:count{verb="INSERT"} 1',
|
||||||
'queries:msec{verb="INSERT"} 800',
|
'queries:total{verb="INSERT"} 800',
|
||||||
'queries:count{verb="SELECT"} 2',
|
'queries:count{verb="SELECT"} 2',
|
||||||
'queries:msec{verb="SELECT"} 500',
|
'queries:total{verb="SELECT"} 500',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue