aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xprometheus.py93
1 files changed, 93 insertions, 0 deletions
diff --git a/prometheus.py b/prometheus.py
new file mode 100755
index 0000000..8a053f1
--- /dev/null
+++ b/prometheus.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+from ejabberdrpc import EjabberdMetrics
+
+import time
+import threading
+import socket
+from http.server import BaseHTTPRequestHandler, HTTPServer
+from socketserver import ThreadingMixIn
+
+class _ThreadingSimpleServer(ThreadingMixIn, HTTPServer):
+ """Thread per request HTTP server."""
+ # Make worker threads "fire and forget". Beginning with Python 3.7 this
+ # prevents a memory leak because ``ThreadingMixIn`` starts to gather all
+ # non-daemon threads in a list in order to join on them at server close.
+ # Enabling daemon threads virtually makes ``_ThreadingSimpleServer`` the
+ # same as Python 3.7's ``ThreadingHTTPServer``.
+ daemon_threads = True
+ address_family = socket.AF_INET6
+
+
+class Prometheus():
+ def __init__(self, metrics):
+ self._metrics = metrics
+
+ def _parse_metric(self, name, value, tags=None):
+ output = name
+ if isinstance(tags, dict):
+ output += "{"
+ first = True
+ for k, v in tags.items():
+ if not first:
+ output += ', '
+ else:
+ first = False
+ output += k+'="'+v+'"'
+ output += '}'
+ return output + ' {}\n'.format(value)
+
+ def _get_metrics(self):
+ output = ""
+
+ output += self._parse_metric("ejabberd_registered_total", self._metrics.get_registered())
+
+ for host in self._metrics.get_vhosts():
+ output += self._parse_metric("ejabberd_registered_vhosts", self._metrics.get_registered(host), {"vhost": host})
+
+ for k, v in self._metrics.get_online_by_node(vhost=host).items():
+ output += self._parse_metric("ejabberd_online_vhost_node", v, {"vhost": host, "node": k})
+
+ for node in self._metrics.get_nodes():
+ for k, v in self._metrics.get_online_by_status(node=node, vhost=host).items():
+ output += self._parse_metric("ejabberd_online_status", v, {"vhost": host, "node": node, "status": k})
+ for k, v in self._metrics.get_online_by_connection(node=node, vhost=host).items():
+ output += self._parse_metric("ejabberd_online_connection", v, {"vhost": host, "node": node, "connection": k})
+ for k, v in self._metrics.get_online_by_client(node=node, vhost=host).items():
+ output += self._parse_metric("ejabberd_online_client", v, {"vhost": host, "node": node, "client": k})
+ for k, v in self._metrics.get_online_by_ipversion(node=node, vhost=host).items():
+ output += self._parse_metric("ejabberd_online_ipversion", v, {"vhost": host, "node": node, "ipversion": str(k)})
+
+ # next four lines should be dropped - it should be calc by ejabberd_online_vhost_node
+ for k, v in self._metrics.get_online_by_node().items():
+ output += self._parse_metric("ejabberd_online_node_total", v, {"node": k})
+ for k, v in self._metrics.get_online_by_vhost().items():
+ output += self._parse_metric("ejabberd_online_vhost_total", v, {"vhost": k})
+
+ return output
+
+
+ def listen(self, port, addr='::'):
+ """Starts an HTTP server for prometheus metrics as a daemon thread"""
+ class myHandler(BaseHTTPRequestHandler):
+ def do_GET(r):
+ r.send_response(200)
+ r.send_header('Content-type', 'text/html')
+ r.end_headers()
+ result = self._get_metrics()
+ r.wfile.write(result.encode('utf-8'))
+
+
+ httpd = _ThreadingSimpleServer((addr, port), myHandler)
+ t = threading.Thread(target=httpd.serve_forever)
+ t.daemon = True
+ t.start()
+
+if __name__ == "__main__":
+ metrics = EjabberdMetrics("http://[::1]:4560")
+ prom = Prometheus(metrics)
+ prom.listen(8080)
+ while True:
+ metrics.update()
+ time.sleep(10)