aboutsummaryrefslogtreecommitdiffstats
path: root/ejabberdrpc.py
diff options
context:
space:
mode:
authornico <nico@magicbroccoli.de>2020-04-28 14:11:49 +0200
committernico <nico@magicbroccoli.de>2020-04-28 14:11:49 +0200
commitd44e4021fe879230adb762972b9080d021176146 (patch)
tree7763fc30bf6e177f8ec5af152994323851a929d5 /ejabberdrpc.py
parentbfcb912595cf15746882603dd9c8c9feaaba410d (diff)
code cleanup
* split up api and metrics class * revamped file nameming to better resemble their function * update prometheus and influx files * fixed version regex to not break on - in version string
Diffstat (limited to 'ejabberdrpc.py')
-rwxr-xr-xejabberdrpc.py373
1 files changed, 0 insertions, 373 deletions
diff --git a/ejabberdrpc.py b/ejabberdrpc.py
deleted file mode 100755
index 6a34cd0..0000000
--- a/ejabberdrpc.py
+++ /dev/null
@@ -1,373 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-import ipaddress
-import re
-
-from packaging import version
-
-# rfc6052: IPv6 Addressing of IPv4/IPv6 Translators
-nat64 = ipaddress.ip_network("64:ff9b::/96")
-
-
-class EjabberdMetrics:
- """
- class to fetch metrics per xmlrpc
- """
- def __init__(self, url, login=None, api="rpc", muc_host: str = 'conference'):
- self._login = login
- self.muc_host = muc_host
- if api == "rpc":
- self.url = url
- self._cmd = self._rpc
- else:
- import requests
-
- self._url = url
- self.session = requests.Session()
- self._cmd = self._rest
-
- @property
- def _auth(self):
- if self._login is not None:
- return f"{self._login['user']}@{self._login['server']}", self._login['password']
- return None
-
- @property
- def _verstring(self):
- if self._login is not None:
- ver_str = re.compile('([1-9][0-9.-]*)')
- status = self._cmd('status', {})
-
- # matches
- tmp = ver_str.findall(status)[0]
-
- # return parsed version string
- return version.parse(tmp)
-
- return None
-
- def _rest(self, command: str, data) -> dict:
- # add authentication header to the session obj
- if self.session.auth is None:
- self.session.auth = self._auth
-
- # post
- r = self.session.post('/'.join([self._url, command]), json=data)
-
- # proceed if response is ok
- if r.ok:
- return r.json()
-
- return {}
-
- def _rpc(self, command: str, data):
- from xmlrpc import client
-
- with client.ServerProxy(self.url) as server:
- fn = getattr(server, command)
- try:
- if self._login is not None:
- return fn(self._login, data)
- return fn(data)
- except:
- return {}
-
- def _client(self, resource):
- clientmap = {
- "Conv6ations for Sum7": ["Conversations with IPv6"],
- "Conversations": [],
- "Pix-Art Messenger": [],
- "Gajim": ["gajim"],
- "Psi+": [],
- "jitsi": [],
- "Dino": ["dino"],
- "poezio": [],
- "profanity": [],
- "Xabber": [],
- "ChatSecure": ["chatsecure"]
- }
-
- for client, names in clientmap.items():
- for c in names:
- if c in resource:
- return client
- if client in resource:
- return client
- return "other"
-
- @staticmethod
- def _ipversion(ip):
- addr = ipaddress.ip_address(ip)
- if addr.version == 6:
- if addr.ipv4_mapped:
- return 4
- if addr in nat64:
- return 4
- return addr.version
-
- def fetch_onlineuser(self):
- tmp = self._cmd("connected_users_info", {})
- if "connected_users_info" not in tmp:
- return tmp
- data = []
- for c in tmp["connected_users_info"]:
- if "session" not in c:
- continue
- user = {}
- for attrs in c["session"]:
- for k, v in attrs.items():
- user[k] = v
- data.append(user)
- return data
-
- def fetch_nodes(self):
- result = self._cmd("list_cluster", {})
- if "nodes" not in result:
- return result
- data = []
- for node in result["nodes"]:
- data.append(node["node"])
- return data
-
- def fetch_vhosts(self):
- result = self._cmd("registered_vhosts", {})
- if "vhosts" not in result:
- return result
- data = []
- for vhost in result["vhosts"]:
- data.append(vhost["vhost"])
- return data
-
- def fetch_s2s_in(self):
- result = self._cmd("incoming_s2s_number", {})
- if "s2s_incoming" not in result:
- return result
- return result["s2s_incoming"]
-
- def fetch_s2s_out(self):
- result = self._cmd("outgoing_s2s_number", {})
- if "s2s_outgoing" not in result:
- return result
- return result["s2s_outgoing"]
-
- def fetch_registered(self, vhost=None):
- if vhost is None:
- result = self._cmd("stats", {"name":"registeredusers"})
- if "stat" in result:
- return result["stat"]
- else:
- result = self._cmd("stats_host", {"name":"registeredusers", "host": vhost})
- if "stat" in result:
- return result["stat"]
-
- def fetch_muc(self, vhost=None):
- host = "global"
- if vhost is not None:
- if self._verstring.major >= 19:
- host = '.'.join([self.muc_host, vhost])
- else:
- host = vhost
- result = self._cmd("muc_online_rooms", {"host": host})
- if "rooms" in result:
- return len(result["rooms"])
- return len(result)
-
- def update(self):
- # nodes
- self._nodes = self.fetch_nodes()
-
- # vhosts
- self._vhosts = self.fetch_vhosts()
-
- # registered
- if not hasattr(self, "_registered"):
- self._registered = {}
- self._registered[None] = self.fetch_registered()
-
- # muc
- if not hasattr(self, "_muc"):
- self._muc = {}
- self._muc[None] = self.fetch_muc()
-
- # registered + muc
- for vhost in self._vhosts:
- self._registered[vhost] = self.fetch_registered(vhost)
- self._muc[vhost] = self.fetch_muc(vhost)
-
- # online user
- self._onlineuser = self.fetch_onlineuser()
-
- # s2s
- self._s2s_in = self.fetch_s2s_in()
- self._s2s_out = self.fetch_s2s_out()
-
- def get_online_by(self, by="node", parse=None, vhost=None, node=None):
- parser = parse or (lambda a: a)
- if not hasattr(self, "_onlineuser"):
- self._onlineuser = self.fetch_onlineuser()
- data = {}
-
- for conn in self._onlineuser:
- if vhost is not None and vhost not in conn["jid"]:
- continue
- if node is not None and node != conn["node"]:
- continue
- if by not in conn:
- continue
- value = parser(conn[by])
- if value not in data:
- data[value] = 1
- else:
- data[value] += 1
- return data
-
- def get_online_by_node(self, vhost=None):
- return self.get_online_by("node", vhost=vhost)
-
- def get_online_by_vhost(self, node=None):
- return self.get_online_by("jid", parse=lambda jid: jid[jid.find("@")+1:jid.find("/")], node=node)
-
- def get_online_by_status(self, vhost=None, node=None):
- return self.get_online_by("status", vhost=vhost, node=node)
-
- def get_online_by_connection(self, vhost=None, node=None):
- return self.get_online_by("connection", vhost=vhost, node=node)
-
- def get_online_by_client(self, vhost=None, node=None):
- return self.get_online_by("resource", parse=self._client, vhost=vhost, node=node)
-
- def get_online_by_ipversion(self, vhost=None, node=None):
- return self.get_online_by("ip", parse=self._ipversion, vhost=vhost, node=node)
-
- def get_online_client_by(self, by="ip", parse=None, vhost=None, node=None):
- parser = parse or self._ipversion
- if not hasattr(self, "_onlineuser"):
- self._onlineuser = self.fetch_onlineuser()
- data = {}
-
- for conn in self._onlineuser:
- client = "other"
- if "resource" in conn:
- client = self._client(conn["resource"])
- if client not in data:
- data[client] = {}
- if vhost is not None and vhost not in conn["jid"]:
- continue
- if node is not None and node != conn["node"]:
- continue
- if by not in conn:
- continue
- value = parser(conn[by])
- if value not in data[client]:
- data[client][value] = 1
- else:
- data[client][value] += 1
- return data
-
- def get_online_client_by_ipversion(self, vhost=None, node=None):
- return self.get_online_client_by("ip", parse=self._ipversion, vhost=vhost, node=node)
-
- def get_registered(self, vhost=None):
- if not hasattr(self, "_registered"):
- self._registered = {}
- if vhost not in self._registered:
- self._registered[vhost] = self.fetch_registered(vhost)
- return self._registered[vhost]
-
- def get_muc(self, vhost=None):
- if not hasattr(self, "_muc"):
- self._muc = {}
- if vhost not in self._muc:
- self._muc[vhost] = self.fetch_muc(vhost)
- return self._muc[vhost]
-
- def get_vhosts(self):
- if not hasattr(self, "_vhosts"):
- self._vhosts = self.fetch_vhosts()
- return self._vhosts
-
- def get_s2s_in(self):
- if not hasattr(self, "_s2s_in"):
- self._s2s_in = self.fetch_s2s_in()
- return self._s2s_in
-
- def get_s2s_out(self):
- if not hasattr(self, "_s2s_out"):
- self._s2s_out = self.fetch_s2s_out()
- return self._s2s_out
-
- def get_vhost_metrics(self, vhost):
- data = {
- "registered": self.get_registered(vhost),
- "muc": self.get_muc(vhost),
- "online_by_status": self.get_online_by_status(vhost),
- "online_by_client": self.get_online_by_client(vhost),
- "online_by_ipversion": self.get_online_by_ipversion(vhost),
- "online_by_connection": self.get_online_by_connection(vhost),
- "online_by_node": self.get_online_by_node(vhost)
- }
-
- return data
-
- def get_nodes(self):
- if not hasattr(self, "_nodes"):
- self._nodes = self.fetch_nodes()
- return self._nodes
-
- def get_node_metrics(self, node):
- data = {
- "online_by_status": self.get_online_by_status(node=node),
- "online_by_client": self.get_online_by_client(node=node),
- "online_by_ipversion": self.get_online_by_ipversion(node=node),
- "online_by_connection": self.get_online_by_connection(node=node),
- "online_by_vhost": self.get_online_by_vhost(node=node)
- }
-
- return data
-
- def get_all(self):
- data = {
- "registered": self.get_registered(),
- "muc": self.get_muc(),
- "online_by_status": self.get_online_by_status(),
- "online_by_client": self.get_online_by_client(),
- "online_by_ipversion": self.get_online_by_ipversion(),
- "online_by_connection": self.get_online_by_connection(),
- "online_by_node": self.get_online_by_node(),
- "online_by_vhost": self.get_online_by_vhost()
- }
-
- vhosts = {}
- for host in self.get_vhosts():
- vhosts[host] = self.get_vhost_metrics(host)
- data["vhosts"] = vhosts
-
- nodes = {}
- for node in self.get_nodes():
- nodes[node] = self.get_node_metrics(node)
-
- data["online_client_by_ipversion"] = self.get_online_client_by_ipversion()
- data["nodes"] = nodes
-
- data["s2s_in"] = self.get_s2s_in()
- data["s2s_out"] = self.get_s2s_out()
- return data
-
-
-if __name__ == "__main__":
- import json
- from config import Config
-
- # load config
- config = Config()
-
- # credentials and parameters
- url = config.get('url', default='http://localhost:5280/api')
- login = config.get('login', default=None)
- api = config.get('api', default='rest')
-
- # init handler
- metrics = EjabberdMetrics(url, login, api)
-
- data = metrics.get_all()
- print(json.dumps(data, indent=True))