2019-10-17 07:01:00 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2020-06-09 20:17:00 +02:00
|
|
|
import logging
|
2021-04-17 17:58:42 +02:00
|
|
|
from http.server import BaseHTTPRequestHandler, HTTPServer, ThreadingHTTPServer
|
2020-06-09 20:56:01 +02:00
|
|
|
from socket import AF_INET6
|
2020-06-26 00:55:49 +02:00
|
|
|
from time import time
|
2020-06-09 20:17:00 +02:00
|
|
|
from urllib.parse import parse_qs, urlparse
|
2020-06-26 00:55:49 +02:00
|
|
|
|
2020-06-29 11:03:49 +02:00
|
|
|
from prometheus_client import CollectorRegistry, Gauge, generate_latest, CONTENT_TYPE_LATEST
|
2020-06-09 20:17:00 +02:00
|
|
|
|
2020-02-16 20:19:03 +01:00
|
|
|
from config import Config
|
2020-04-28 14:11:49 +02:00
|
|
|
from metrics import EjabberdMetrics
|
2020-02-16 20:19:03 +01:00
|
|
|
|
|
|
|
|
2020-06-09 20:17:00 +02:00
|
|
|
class DynamicMetricsHandler(BaseHTTPRequestHandler):
|
|
|
|
"""HTTP handler that gives metrics from ``core.REGISTRY``."""
|
2020-06-29 11:03:49 +02:00
|
|
|
|
2020-06-09 20:17:00 +02:00
|
|
|
def do_GET(self):
|
|
|
|
params = parse_qs(urlparse(self.path).query)
|
|
|
|
registry = self.generator(params)
|
2020-06-29 11:03:49 +02:00
|
|
|
if "name[]" in params:
|
|
|
|
registry = registry.restricted_registry(params["name[]"])
|
2020-06-09 20:17:00 +02:00
|
|
|
try:
|
|
|
|
output = generate_latest(registry)
|
2020-07-19 22:34:11 +02:00
|
|
|
except Exception as exception:
|
|
|
|
self.send_error(500, f"error generating metric output: {exception}")
|
2020-06-09 20:17:00 +02:00
|
|
|
raise
|
|
|
|
self.send_response(200)
|
2020-06-29 11:03:49 +02:00
|
|
|
self.send_header("Content-Type", CONTENT_TYPE_LATEST)
|
2020-06-09 20:17:00 +02:00
|
|
|
self.end_headers()
|
|
|
|
self.wfile.write(output)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def factory(registry_generator):
|
2020-06-29 11:03:49 +02:00
|
|
|
DynMetricsHandler = type("MetricsHandler", (DynamicMetricsHandler, object), {"generator": registry_generator})
|
2020-06-09 20:17:00 +02:00
|
|
|
return DynMetricsHandler
|
2019-10-17 07:01:00 +02:00
|
|
|
|
2020-06-26 00:55:49 +02:00
|
|
|
|
|
|
|
class Prometheus:
|
2019-10-17 07:01:00 +02:00
|
|
|
def __init__(self, metrics):
|
2020-06-09 20:17:00 +02:00
|
|
|
self.ttl = 10
|
|
|
|
self._last_update = 0
|
2019-10-17 07:01:00 +02:00
|
|
|
self._metrics = metrics
|
2020-06-29 11:03:49 +02:00
|
|
|
|
2020-06-09 20:17:00 +02:00
|
|
|
def handler(self, metrics_handler):
|
|
|
|
now = time()
|
2020-06-09 20:22:20 +02:00
|
|
|
if now >= (self._last_update + self.ttl):
|
2020-06-09 20:17:00 +02:00
|
|
|
self._metrics.update()
|
|
|
|
self._last_update = now
|
|
|
|
|
|
|
|
registry = CollectorRegistry(auto_describe=True)
|
|
|
|
|
2020-06-29 11:03:49 +02:00
|
|
|
Gauge("ejabberd_node_s2s_in", "count of incoming server-to-server connection", registry=registry).set(
|
|
|
|
self._metrics.get_s2s_in()
|
|
|
|
)
|
|
|
|
Gauge("ejabberd_node_s2s_out", "count of outgoing server-to-server connection", registry=registry).set(
|
|
|
|
self._metrics.get_s2s_out()
|
|
|
|
)
|
2020-06-09 20:17:00 +02:00
|
|
|
|
2020-06-26 08:25:10 +02:00
|
|
|
nodename = self._metrics.nodename
|
2020-06-29 11:03:49 +02:00
|
|
|
Gauge("ejabberd_node_uptime", "uptime of ejabberd service", ["node"], registry=registry).labels(nodename).set(
|
|
|
|
self._metrics.get_uptime()
|
|
|
|
)
|
|
|
|
Gauge("ejabberd_node_proccess", "count of pejabber proccess", ["node"], registry=registry).labels(nodename).set(
|
|
|
|
self._metrics.get_processes()
|
|
|
|
)
|
2020-06-26 08:25:10 +02:00
|
|
|
|
2020-06-09 20:17:00 +02:00
|
|
|
labelnames_vhost = ["vhost"]
|
|
|
|
|
2020-06-29 11:03:49 +02:00
|
|
|
registered_vhosts = Gauge(
|
|
|
|
"ejabberd_registered_vhosts", "count of user per vhost", labelnames_vhost, registry=registry
|
|
|
|
)
|
|
|
|
muc = Gauge("ejabberd_muc", "count of muc's per vhost", labelnames_vhost, registry=registry)
|
|
|
|
|
|
|
|
online_vhost_node = Gauge(
|
|
|
|
"ejabberd_online_vhost_node", "count of client connections", ["vhost", "node"], registry=registry
|
|
|
|
)
|
|
|
|
|
|
|
|
online_status = Gauge(
|
|
|
|
"ejabberd_online_status", "count of client connections", ["vhost", "node", "status"], registry=registry
|
|
|
|
)
|
|
|
|
online_connection = Gauge(
|
|
|
|
"ejabberd_online_connection",
|
|
|
|
"count of client connections",
|
|
|
|
["vhost", "node", "connection"],
|
|
|
|
registry=registry,
|
|
|
|
)
|
|
|
|
online_client = Gauge(
|
|
|
|
"ejabberd_online_client", "count of client software", ["vhost", "node", "client"], registry=registry
|
|
|
|
)
|
|
|
|
online_ipversion = Gauge(
|
|
|
|
"ejabberd_online_ipversion", "count of client software", ["vhost", "node", "ipversion"], registry=registry
|
|
|
|
)
|
|
|
|
online_client_ipversion = Gauge(
|
|
|
|
"ejabberd_online_client_ipversion",
|
|
|
|
"count of client software",
|
|
|
|
["vhost", "node", "client", "ipversion"],
|
|
|
|
registry=registry,
|
|
|
|
)
|
2020-06-09 20:17:00 +02:00
|
|
|
|
2019-10-17 07:01:00 +02:00
|
|
|
for host in self._metrics.get_vhosts():
|
2020-06-26 00:55:49 +02:00
|
|
|
labels_vhost = host
|
2020-06-09 20:17:00 +02:00
|
|
|
|
|
|
|
registered_vhosts.labels(labels_vhost).set(self._metrics.get_registered(host))
|
|
|
|
muc.labels(labels_vhost).set(self._metrics.get_muc(host))
|
2019-10-17 07:01:00 +02:00
|
|
|
|
|
|
|
for k, v in self._metrics.get_online_by_node(vhost=host).items():
|
2020-06-26 00:55:49 +02:00
|
|
|
online_vhost_node.labels(host, k).set(v)
|
2019-10-17 07:01:00 +02:00
|
|
|
|
|
|
|
for node in self._metrics.get_nodes():
|
|
|
|
for k, v in self._metrics.get_online_by_status(node=node, vhost=host).items():
|
2020-06-26 00:55:49 +02:00
|
|
|
online_status.labels(host, node, k).set(v)
|
2019-10-17 07:01:00 +02:00
|
|
|
for k, v in self._metrics.get_online_by_connection(node=node, vhost=host).items():
|
2020-06-26 00:55:49 +02:00
|
|
|
online_connection.labels(host, node, k).set(v)
|
2019-10-17 07:01:00 +02:00
|
|
|
for k, v in self._metrics.get_online_by_client(node=node, vhost=host).items():
|
2020-06-26 00:55:49 +02:00
|
|
|
online_client.labels(host, node, k).set(v)
|
2019-10-17 07:01:00 +02:00
|
|
|
for k, v in self._metrics.get_online_by_ipversion(node=node, vhost=host).items():
|
2020-06-26 00:55:49 +02:00
|
|
|
online_ipversion.labels(host, node, k).set(v)
|
|
|
|
for client, data in self._metrics.get_online_client_by_ipversion(node=node, vhost=host).items():
|
2019-10-17 13:45:55 +02:00
|
|
|
for k, v in data.items():
|
2020-06-26 00:55:49 +02:00
|
|
|
online_client_ipversion.labels(host, node, client, str(k)).set(v)
|
2019-10-17 07:01:00 +02:00
|
|
|
|
2020-06-09 20:17:00 +02:00
|
|
|
return registry
|
2019-10-17 07:01:00 +02:00
|
|
|
|
2020-06-09 20:17:00 +02:00
|
|
|
def listen(self, addr=("127.0.0.1", 8080)):
|
2020-06-09 20:56:01 +02:00
|
|
|
if "::" in addr[0]:
|
|
|
|
HTTPServer.address_family = AF_INET6
|
2021-04-17 17:58:42 +02:00
|
|
|
server = ThreadingHTTPServer(addr, DynamicMetricsHandler.factory(self.handler))
|
2020-06-09 20:17:00 +02:00
|
|
|
server.serve_forever()
|
2019-10-17 07:01:00 +02:00
|
|
|
|
2019-12-07 16:01:03 +01:00
|
|
|
|
2020-02-16 20:19:03 +01:00
|
|
|
if __name__ == "__main__":
|
2019-12-07 16:01:03 +01:00
|
|
|
# load config
|
2020-02-16 20:19:03 +01:00
|
|
|
config = Config()
|
2020-06-29 11:03:49 +02:00
|
|
|
if config.get("debug", default=False):
|
2020-06-09 20:17:00 +02:00
|
|
|
logging.getLogger().setLevel(logging.DEBUG)
|
2019-12-07 16:01:03 +01:00
|
|
|
|
2020-02-16 20:19:03 +01:00
|
|
|
# credentials and parameters
|
2020-06-29 11:03:49 +02:00
|
|
|
url = config.get("url", default="http://[::1]:5280/api")
|
|
|
|
login = config.get("login", default=None)
|
|
|
|
api = config.get("api", default="rest")
|
2019-12-07 16:01:03 +01:00
|
|
|
|
2020-02-16 20:19:03 +01:00
|
|
|
# config prometheus
|
2020-06-29 11:03:49 +02:00
|
|
|
prom_addr = config.get("prometheus_address", default="127.0.0.1")
|
|
|
|
prom_port = config.get("prometheus_port", default=8080)
|
2019-12-07 16:01:03 +01:00
|
|
|
|
|
|
|
metrics = EjabberdMetrics(url, login, api)
|
2019-10-17 07:01:00 +02:00
|
|
|
prom = Prometheus(metrics)
|
2020-06-29 11:03:49 +02:00
|
|
|
prom.ttl = config.get("prometheus_cache_ttl", default=10)
|
2020-06-09 20:17:00 +02:00
|
|
|
prom.listen((prom_addr, prom_port))
|