Skip to content

Commit 2d4c863

Browse files
authored
Add gauge registry (census-instrumentation#503)
1 parent 056d364 commit 2d4c863

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

opencensus/metrics/export/gauge.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
# limitations under the License.
1414

1515
from collections import OrderedDict
16+
from datetime import datetime
1617
import six
1718
import threading
1819

1920
from opencensus.common import utils
2021
from opencensus.metrics.export import metric
2122
from opencensus.metrics.export import metric_descriptor
23+
from opencensus.metrics.export import metric_producer
2224
from opencensus.metrics.export import point as point_module
2325
from opencensus.metrics.export import time_series
2426
from opencensus.metrics.export import value as value_module
@@ -430,3 +432,57 @@ class DerivedLongGauge(LongGaugeMixin, DerivedGauge):
430432

431433
class DerivedDoubleGauge(DoubleGaugeMixin, DerivedGauge):
432434
"""Gauge for derived float-valued measurements."""
435+
436+
437+
class Registry(metric_producer.MetricProducer):
438+
"""A collection of gauges to be exported together.
439+
440+
Each registered gauge must have a unique `descriptor.name`.
441+
"""
442+
443+
def __init__(self):
444+
self.gauges = {}
445+
self._gauges_lock = threading.Lock()
446+
447+
def __repr__(self):
448+
return ('{}(gauges={}'
449+
.format(
450+
type(self).__name__,
451+
self.gauges
452+
))
453+
454+
def add_gauge(self, gauge):
455+
"""Add `gauge` to the registry and return it.
456+
457+
Raises a `ValueError` if another gauge with the same name already
458+
exists in the registry.
459+
460+
:type gauge: class:`LongGauge`, class:`DoubleGauge`,
461+
:class:`DerivedLongGauge`, or :class:`DerivedDoubleGauge`
462+
:param gauge: The gauge to add to the registry.
463+
464+
:type gauge: class:`LongGauge`, class:`DoubleGauge`,
465+
:class:`DerivedLongGauge`, or :class:`DerivedDoubleGauge`
466+
:return: The gauge that was added to the registry.
467+
"""
468+
if gauge is None:
469+
raise ValueError
470+
name = gauge.descriptor.name
471+
with self._gauges_lock:
472+
if name in self.gauges:
473+
raise ValueError(
474+
'Another gauge named "{}" is already registered'
475+
.format(name))
476+
self.gauges[name] = gauge
477+
478+
def get_metrics(self):
479+
"""Get a metric for each gauge in the registry at the current time.
480+
481+
:rtype: set(:class:`opencensus.metrics.export.metric.Metric`)
482+
:return: A set of `Metric`s, one for each registered gauge.
483+
"""
484+
now = datetime.now()
485+
metrics = set()
486+
for gauge in self.gauges.values():
487+
metrics.add(gauge.get_metric(now))
488+
return metrics

tests/unit/metrics/export/test_gauge.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,3 +424,46 @@ def test_create_default_time_series(self):
424424
self.assertIs(default_point, point3)
425425
self.assertEqual(default_point.get_value(), 12)
426426
unused_mock_fn2.assert_not_called()
427+
428+
429+
class TestRegistry(unittest.TestCase):
430+
def test_add_gauge(self):
431+
reg = gauge.Registry()
432+
433+
with self.assertRaises(ValueError):
434+
reg.add_gauge(None)
435+
436+
gauge1 = Mock()
437+
gauge1.descriptor.name = 'gauge1'
438+
gauge2 = Mock()
439+
gauge2.descriptor.name = 'gauge2'
440+
441+
reg.add_gauge(gauge1)
442+
self.assertDictEqual(reg.gauges, {'gauge1': gauge1})
443+
reg.add_gauge(gauge2)
444+
self.assertDictEqual(reg.gauges, {'gauge1': gauge1, 'gauge2': gauge2})
445+
446+
with self.assertRaises(ValueError):
447+
reg.add_gauge(gauge2)
448+
449+
def test_get_metrics(self):
450+
reg = gauge.Registry()
451+
452+
with self.assertRaises(ValueError):
453+
reg.add_gauge(None)
454+
455+
gauge1 = Mock()
456+
gauge1.descriptor.name = 'gauge1'
457+
metric1 = Mock()
458+
gauge1.get_metric.return_value = metric1
459+
460+
gauge2 = Mock()
461+
gauge2.descriptor.name = 'gauge2'
462+
metric2 = Mock()
463+
gauge2.get_metric.return_value = metric2
464+
465+
self.assertSetEqual(reg.get_metrics(), set())
466+
reg.add_gauge(gauge1)
467+
self.assertSetEqual(reg.get_metrics(), {metric1})
468+
reg.add_gauge(gauge2)
469+
self.assertSetEqual(reg.get_metrics(), {metric1, metric2})

0 commit comments

Comments
 (0)