Skip to content
Snippets Groups Projects
Commit 992018d1 authored by Richard van der Hoff's avatar Richard van der Hoff
Browse files

mechanism to render metrics with alternative names

parent 80fa610f
No related branches found
No related tags found
No related merge requests found
...@@ -17,24 +17,33 @@ ...@@ -17,24 +17,33 @@
from itertools import chain from itertools import chain
# TODO(paul): I can't believe Python doesn't have one of these def flatten(items):
def map_concat(func, items): """Flatten a list of lists
# flatten a list-of-lists
return list(chain.from_iterable(map(func, items))) Args:
items: iterable[iterable[X]]
Returns:
list[X]: flattened list
"""
return list(chain.from_iterable(items))
class BaseMetric(object): class BaseMetric(object):
"""Base class for metrics which report a single value per label set """Base class for metrics which report a single value per label set
""" """
def __init__(self, name, labels=[]): def __init__(self, name, labels=[], alternative_names=[]):
""" """
Args: Args:
name (str): principal name for this metric name (str): principal name for this metric
labels (list(str)): names of the labels which will be reported labels (list(str)): names of the labels which will be reported
for this metric for this metric
alternative_names (iterable(str)): list of alternative names for
this metric. This can be useful to provide a migration path
when renaming metrics.
""" """
self.name = name self._names = [name] + list(alternative_names)
self.labels = labels # OK not to clone as we never write it self.labels = labels # OK not to clone as we never write it
def dimension(self): def dimension(self):
...@@ -55,6 +64,22 @@ class BaseMetric(object): ...@@ -55,6 +64,22 @@ class BaseMetric(object):
for k, v in zip(self.labels, values)]) for k, v in zip(self.labels, values)])
) )
def _render_for_labels(self, label_values, value):
"""Render this metric for a single set of labels
Args:
label_values (list[str]): values for each of the labels
value: value of the metric at with these labels
Returns:
iterable[str]: rendered metric
"""
rendered_labels = self._render_key(label_values)
return (
"%s%s %.12g" % (name, rendered_labels, value)
for name in self._names
)
def render(self): def render(self):
"""Render this metric """Render this metric
...@@ -110,11 +135,11 @@ class CounterMetric(BaseMetric): ...@@ -110,11 +135,11 @@ class CounterMetric(BaseMetric):
def inc(self, *values): def inc(self, *values):
self.inc_by(1, *values) self.inc_by(1, *values)
def render_item(self, k):
return ["%s%s %.12g" % (self.name, self._render_key(k), self.counts[k])]
def render(self): def render(self):
return map_concat(self.render_item, sorted(self.counts.keys())) return flatten(
self._render_for_labels(k, self.counts[k])
for k in sorted(self.counts.keys())
)
class CallbackMetric(BaseMetric): class CallbackMetric(BaseMetric):
...@@ -131,10 +156,12 @@ class CallbackMetric(BaseMetric): ...@@ -131,10 +156,12 @@ class CallbackMetric(BaseMetric):
value = self.callback() value = self.callback()
if self.is_scalar(): if self.is_scalar():
return ["%s %.12g" % (self.name, value)] return list(self._render_for_labels([], value))
return ["%s%s %.12g" % (self.name, self._render_key(k), value[k]) return flatten(
for k in sorted(value.keys())] self._render_for_labels(k, value[k])
for k in sorted(value.keys())
)
class DistributionMetric(object): class DistributionMetric(object):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment