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

Reply via email to