Ema has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/370962 )
Change subject: Add prometheus metrics ...................................................................... Add prometheus metrics Extend PyBal instrumentation by adding support for metrics in prometheus format under /metrics. Bug: T171710 Change-Id: I3fb22fce93d0f9fed814af3a6e8c7b7d07c9b135 --- M pybal/instrumentation.py A pybal/metrics.py M pybal/monitor.py M pybal/test/test_monitor.py M pybal/test/test_monitors.py M requirements.txt M tox.ini 7 files changed, 68 insertions(+), 4 deletions(-) Approvals: Ema: Looks good to me, approved Mark Bergsma: Looks good to me, but someone else must approve jenkins-bot: Verified diff --git a/pybal/instrumentation.py b/pybal/instrumentation.py index da04b11..e77c333 100644 --- a/pybal/instrumentation.py +++ b/pybal/instrumentation.py @@ -16,6 +16,13 @@ """ from twisted.web.resource import Resource + +try: + from prometheus_client.twisted import MetricsResource + prometheus_support = True +except ImportError: + prometheus_support = False + import json @@ -50,6 +57,8 @@ return PoolsRoot() if path == 'alerts': return Alerts() + if prometheus_support and path == 'metrics': + return MetricsResource() else: return Resp404() diff --git a/pybal/metrics.py b/pybal/metrics.py new file mode 100644 index 0000000..fb740e5 --- /dev/null +++ b/pybal/metrics.py @@ -0,0 +1,27 @@ +""" +metrics.py + +Metrics class implementations for PyBal +""" + +try: + import prometheus_client + metrics_implementation = 'prometheus' +except ImportError: + metrics_implementation = 'dummy' + +class DummyMetric(object): + def __init__(self, **kwargs): + pass + + def labels(self, **kwargs): + return self + +class DummyCounter(DummyMetric): + def inc(self, **kwargs): + pass + +if metrics_implementation == 'prometheus': + Counter = prometheus_client.Counter +else: + Counter = DummyCounter diff --git a/pybal/monitor.py b/pybal/monitor.py index dd62b5a..d8d187f 100644 --- a/pybal/monitor.py +++ b/pybal/monitor.py @@ -7,6 +7,7 @@ from twisted.internet import reactor from . import util import logging +from pybal.metrics import Counter _log = util._log @@ -16,6 +17,20 @@ Base class for all monitoring protocols. Declares a few obligatory abstract methods, and some commonly useful functions. """ + + __name__ = '' + + metric_labelnames = ('service', 'host', 'monitor') + metric_keywords = { + 'labelnames': metric_labelnames, + 'namespace': 'pybal', + 'subsystem': 'monitor' + } + + metrics = { + 'up_transitions_total': Counter('up_transitions_total', 'Monitor up transition count', **metric_keywords), + 'down_transitions_total': Counter('down_transitions_total', 'Monitor down transition count', **metric_keywords), + } def __init__(self, coordinator, server, configuration={}, reactor=reactor): """Constructor""" @@ -31,6 +46,12 @@ # Install cleanup handler self.reactor.addSystemEventTrigger('before', 'shutdown', self.stop) + + self.metric_labels = { + 'service': self.server.lvsservice.name, + 'host': self.server.host, + 'monitor': self.name() + } def run(self): """Start the monitoring""" @@ -55,6 +76,9 @@ if self.coordinator: self.coordinator.resultUp(self) + self.metrics['up_transitions_total'].labels(**self.metric_labels).inc() + + def _resultDown(self, reason=None): """Sets own monitoring state to Down and notifies the coordinator if this implies a state change.""" @@ -64,6 +88,8 @@ if self.coordinator: self.coordinator.resultDown(self, reason) + self.metrics['down_transitions_total'].labels(**self.metric_labels).inc() + def report(self, text, level=logging.DEBUG): """Common method for reporting/logging check results.""" msg = "%s (%s): %s" % ( diff --git a/pybal/test/test_monitor.py b/pybal/test/test_monitor.py index 6c5bcaf..d899505 100644 --- a/pybal/test/test_monitor.py +++ b/pybal/test/test_monitor.py @@ -21,7 +21,7 @@ def setUp(self): super(MonitoringProtocolTestCase, self).setUp() self.monitor = pybal.monitor.MonitoringProtocol( - self.coordinator, None, self.config) + self.coordinator, self.server, self.config) self.monitor.__name__ = 'TestMonitor' self.reactor = twisted.internet.reactor diff --git a/pybal/test/test_monitors.py b/pybal/test/test_monitors.py index c38a370..ed5d05f 100644 --- a/pybal/test/test_monitors.py +++ b/pybal/test/test_monitors.py @@ -31,7 +31,7 @@ def testInit(self): """Test `IdleConnectionMonitoringProtocol.__init__`.""" - monitor = IdleConnectionMonitoringProtocol(None, None, self.config) + monitor = IdleConnectionMonitoringProtocol(None, self.server, self.config) self.assertEquals( monitor.maxDelay, IdleConnectionMonitoringProtocol.MAX_DELAY) self.assertEquals( @@ -40,7 +40,7 @@ ) self.config['idleconnection.max-delay'] = '123' self.config['idleconnection.timeout-clean-reconnect'] = '456' - monitor = IdleConnectionMonitoringProtocol(None, None, self.config) + monitor = IdleConnectionMonitoringProtocol(None, self.server, self.config) self.assertEquals(monitor.maxDelay, 123) self.assertEquals(monitor.toCleanReconnect, 456) @@ -127,7 +127,7 @@ def testInit(self): """Test `DNSQueryMonitoringProtocol.__init__`.""" - monitor = DNSQueryMonitoringProtocol(None, None, self.config) + monitor = DNSQueryMonitoringProtocol(None, self.server, self.config) self.assertEquals(monitor.intvCheck, monitor.INTV_CHECK) self.assertEquals(monitor.toQuery, monitor.TIMEOUT_QUERY) diff --git a/requirements.txt b/requirements.txt index 67d9e47..13e5974 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ twisted PyOpenSSL +prometheus_client diff --git a/tox.ini b/tox.ini index 3de1bc3..a0a04fe 100644 --- a/tox.ini +++ b/tox.ini @@ -10,6 +10,7 @@ twisted mock PyOpenSSL + prometheus_client [testenv:cover] commands = -- To view, visit https://gerrit.wikimedia.org/r/370962 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I3fb22fce93d0f9fed814af3a6e8c7b7d07c9b135 Gerrit-PatchSet: 8 Gerrit-Project: operations/debs/pybal Gerrit-Branch: master Gerrit-Owner: Ema <e...@wikimedia.org> Gerrit-Reviewer: Ema <e...@wikimedia.org> Gerrit-Reviewer: Filippo Giunchedi <fgiunch...@wikimedia.org> Gerrit-Reviewer: Giuseppe Lavagetto <glavage...@wikimedia.org> Gerrit-Reviewer: Mark Bergsma <m...@wikimedia.org> Gerrit-Reviewer: Volans <rcocci...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits