parent
a8b78be75d
commit
5f0cb289c1
5
api.py
5
api.py
|
@ -9,6 +9,7 @@ class EjabberdApi:
|
||||||
"""
|
"""
|
||||||
class to interact with the ejabberd rest/ xmlrpc api
|
class to interact with the ejabberd rest/ xmlrpc api
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, url, login=None, api: str = "rpc"):
|
def __init__(self, url, login=None, api: str = "rpc"):
|
||||||
# api variables
|
# api variables
|
||||||
self._login = login
|
self._login = login
|
||||||
|
@ -25,7 +26,7 @@ class EjabberdApi:
|
||||||
@property
|
@property
|
||||||
def _auth(self) -> (str, None):
|
def _auth(self) -> (str, None):
|
||||||
if self._login is not None:
|
if self._login is not None:
|
||||||
return f"{self._login['user']}@{self._login['server']}", self._login['password']
|
return f"{self._login['user']}@{self._login['server']}", self._login["password"]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _rest(self, command: str, data) -> dict:
|
def _rest(self, command: str, data) -> dict:
|
||||||
|
@ -34,7 +35,7 @@ class EjabberdApi:
|
||||||
self.session.auth = self._auth
|
self.session.auth = self._auth
|
||||||
|
|
||||||
# post
|
# post
|
||||||
r = self.session.post('/'.join([self._url, command]), json=data)
|
r = self.session.post("/".join([self._url, command]), json=data)
|
||||||
|
|
||||||
# proceed if response is ok
|
# proceed if response is ok
|
||||||
if r.ok:
|
if r.ok:
|
||||||
|
|
10
calls.py
10
calls.py
|
@ -14,8 +14,8 @@ class EjabberdApiCalls(EjabberdApi):
|
||||||
@property
|
@property
|
||||||
def nodename(self):
|
def nodename(self):
|
||||||
if self._login is not None:
|
if self._login is not None:
|
||||||
node_str = re.compile('The node \'(.*)\'')
|
node_str = re.compile("The node '(.*)'")
|
||||||
status = self.cmd('status', {})
|
status = self.cmd("status", {})
|
||||||
|
|
||||||
# matches
|
# matches
|
||||||
try:
|
try:
|
||||||
|
@ -32,8 +32,8 @@ class EjabberdApiCalls(EjabberdApi):
|
||||||
@property
|
@property
|
||||||
def verstring(self):
|
def verstring(self):
|
||||||
if self._login is not None:
|
if self._login is not None:
|
||||||
ver_str = re.compile('([1-9][0-9.]+(?![.a-z]))\\b')
|
ver_str = re.compile("([1-9][0-9.]+(?![.a-z]))\\b")
|
||||||
status = self.cmd('status', {})
|
status = self.cmd("status", {})
|
||||||
|
|
||||||
# matches
|
# matches
|
||||||
try:
|
try:
|
||||||
|
@ -117,7 +117,7 @@ class EjabberdApiCalls(EjabberdApi):
|
||||||
host = "global"
|
host = "global"
|
||||||
if vhost is not None:
|
if vhost is not None:
|
||||||
if self.verstring.major >= 19:
|
if self.verstring.major >= 19:
|
||||||
host = '.'.join([muc_host, vhost])
|
host = ".".join([muc_host, vhost])
|
||||||
else:
|
else:
|
||||||
host = vhost
|
host = vhost
|
||||||
result = self.cmd("muc_online_rooms", {"host": host})
|
result = self.cmd("muc_online_rooms", {"host": host})
|
||||||
|
|
36
cleanup.py
36
cleanup.py
|
@ -20,16 +20,16 @@ class EjabberdCleanup(EjabberdApiCalls):
|
||||||
if self.dry:
|
if self.dry:
|
||||||
logging.warning(f"{user}@{host}: dry delete : {reason}")
|
logging.warning(f"{user}@{host}: dry delete : {reason}")
|
||||||
else:
|
else:
|
||||||
self.cmd("unregister", {"host": host, "user": user})
|
self.cmd("unregister", {"host": host, "user": user})
|
||||||
logging.warning(f"{user}@{host}: deleted - {reason}")
|
logging.warning(f"{user}@{host}: deleted - {reason}")
|
||||||
|
|
||||||
def run_user(self, host, user):
|
def run_user(self, host, user):
|
||||||
if self.skip_by_roster:
|
if self.skip_by_roster:
|
||||||
roster = self.cmd("get_roster",{"host": host, "user": user})
|
roster = self.cmd("get_roster", {"host": host, "user": user})
|
||||||
if len(roster) > 0:
|
if len(roster) > 0:
|
||||||
logging.debug(f"{user}@{host}: skipped it has a roster")
|
logging.debug(f"{user}@{host}: skipped it has a roster")
|
||||||
return
|
return
|
||||||
last = self.cmd("get_last",{"host": host, "user": user})
|
last = self.cmd("get_last", {"host": host, "user": user})
|
||||||
if self.delete_not_login and last["status"] == "Registered but didn't login":
|
if self.delete_not_login and last["status"] == "Registered but didn't login":
|
||||||
self.delete_user(host, user, "not login")
|
self.delete_user(host, user, "not login")
|
||||||
return
|
return
|
||||||
|
@ -37,14 +37,16 @@ class EjabberdCleanup(EjabberdApiCalls):
|
||||||
last_stamp = last["timestamp"]
|
last_stamp = last["timestamp"]
|
||||||
lastdate = None
|
lastdate = None
|
||||||
try:
|
try:
|
||||||
lastdate = datetime.datetime.strptime(last_stamp,"%Y-%m-%dT%H:%M:%SZ")
|
lastdate = datetime.datetime.strptime(last_stamp, "%Y-%m-%dT%H:%M:%SZ")
|
||||||
except:
|
except:
|
||||||
try:
|
try:
|
||||||
lastdate = datetime.datetime.strptime(last_stamp,"%Y-%m-%dT%H:%M:%S.%fZ")
|
lastdate = datetime.datetime.strptime(last_stamp, "%Y-%m-%dT%H:%M:%S.%fZ")
|
||||||
except:
|
except:
|
||||||
logging.error(f"{user}@{host}: not able to parse '{last_stamp}'")
|
logging.error(f"{user}@{host}: not able to parse '{last_stamp}'")
|
||||||
return
|
return
|
||||||
if lastdate != None and lastdate-datetime.datetime.now() > datetime.timedelta(days=self.offline_since_days):
|
if lastdate != None and lastdate - datetime.datetime.now() > datetime.timedelta(
|
||||||
|
days=self.offline_since_days
|
||||||
|
):
|
||||||
self.delete_user(host, user, f"last seen @ {lastdate}")
|
self.delete_user(host, user, f"last seen @ {lastdate}")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -53,7 +55,7 @@ class EjabberdCleanup(EjabberdApiCalls):
|
||||||
if host in self.ignore_hosts:
|
if host in self.ignore_hosts:
|
||||||
continue
|
continue
|
||||||
logging.info(f"run cleanup for host: {host}")
|
logging.info(f"run cleanup for host: {host}")
|
||||||
for user in self.cmd("registered_users",{"host": host}):
|
for user in self.cmd("registered_users", {"host": host}):
|
||||||
if user in self.ignore_usernames:
|
if user in self.ignore_usernames:
|
||||||
continue
|
continue
|
||||||
self.run_user(host, user)
|
self.run_user(host, user)
|
||||||
|
@ -64,20 +66,20 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
# load config
|
# load config
|
||||||
config = Config()
|
config = Config()
|
||||||
if config.get('debug', default=False):
|
if config.get("debug", default=False):
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
|
||||||
# credentials and parameters
|
# credentials and parameters
|
||||||
url = config.get('url', default='http://localhost:5280/api')
|
url = config.get("url", default="http://localhost:5280/api")
|
||||||
login = config.get('login', default=None)
|
login = config.get("login", default=None)
|
||||||
api = config.get('api', default='rest')
|
api = config.get("api", default="rest")
|
||||||
|
|
||||||
# init handler
|
# init handler
|
||||||
cleaner = EjabberdCleanup(url, login, api)
|
cleaner = EjabberdCleanup(url, login, api)
|
||||||
cleaner.dry = config.get('cleaner_dry',default=False)
|
cleaner.dry = config.get("cleaner_dry", default=False)
|
||||||
cleaner.ignore_hosts = config.get('cleaner_ignore_hosts',default=[])
|
cleaner.ignore_hosts = config.get("cleaner_ignore_hosts", default=[])
|
||||||
cleaner.ignore_usernames = config.get('cleaner_ignore_usernames',default=[])
|
cleaner.ignore_usernames = config.get("cleaner_ignore_usernames", default=[])
|
||||||
cleaner.skip_by_roster = config.get('cleaner_skip_by_roster',default=True)
|
cleaner.skip_by_roster = config.get("cleaner_skip_by_roster", default=True)
|
||||||
cleaner.delete_not_login = config.get('cleaner_delete_not_login',default=True)
|
cleaner.delete_not_login = config.get("cleaner_delete_not_login", default=True)
|
||||||
cleaner.offline_since_days = config.get('cleaner_offline_since_days', default=None)
|
cleaner.offline_since_days = config.get("cleaner_offline_since_days", default=None)
|
||||||
cleaner.run()
|
cleaner.run()
|
||||||
|
|
10
config.py
10
config.py
|
@ -13,11 +13,11 @@ class Config:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# class variables
|
# class variables
|
||||||
self.content = None
|
self.content = None
|
||||||
self.conf_file = Path('/etc/ejabberd-metrics.yml')
|
self.conf_file = Path("/etc/ejabberd-metrics.yml")
|
||||||
|
|
||||||
# dev config overwrite
|
# dev config overwrite
|
||||||
if environ.get('ejabberd_metrics_dev'):
|
if environ.get("ejabberd_metrics_dev"):
|
||||||
self.conf_file = Path('config.yml')
|
self.conf_file = Path("config.yml")
|
||||||
|
|
||||||
# read config file
|
# read config file
|
||||||
self._read()
|
self._read()
|
||||||
|
@ -27,9 +27,9 @@ class Config:
|
||||||
self._check()
|
self._check()
|
||||||
|
|
||||||
# open file as an iostream
|
# open file as an iostream
|
||||||
with open(self.conf_file, 'r', encoding='utf-8') as f:
|
with open(self.conf_file, "r", encoding="utf-8") as f:
|
||||||
try:
|
try:
|
||||||
self.content = YAML(typ='safe').load(f)
|
self.content = YAML(typ="safe").load(f)
|
||||||
|
|
||||||
# catch json decoding errors
|
# catch json decoding errors
|
||||||
except (ParserError, ScannerError) as err:
|
except (ParserError, ScannerError) as err:
|
||||||
|
|
57
influx.py
57
influx.py
|
@ -21,8 +21,8 @@ class Influx:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _rmspace(key: str = None, value: (str, int) = None):
|
def _rmspace(key: str = None, value: (str, int) = None):
|
||||||
try:
|
try:
|
||||||
key = key.replace(' ', '\ ')
|
key = key.replace(" ", "\ ")
|
||||||
value = value.replace(' ', '\ ')
|
value = value.replace(" ", "\ ")
|
||||||
except (TypeError, AttributeError):
|
except (TypeError, AttributeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -36,10 +36,10 @@ class Influx:
|
||||||
|
|
||||||
# create tag_key=tag_value pairs for all elements and append them to name
|
# create tag_key=tag_value pairs for all elements and append them to name
|
||||||
for k, v in tags.items():
|
for k, v in tags.items():
|
||||||
output += ',{}={}'.format(*self._rmspace(k, v))
|
output += ",{}={}".format(*self._rmspace(k, v))
|
||||||
|
|
||||||
# append key=value to name
|
# append key=value to name
|
||||||
output += ' {}={}i {}'.format(*self._rmspace(key, value), ts)
|
output += " {}={}i {}".format(*self._rmspace(key, value), ts)
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def write_metrics(self):
|
def write_metrics(self):
|
||||||
|
@ -47,53 +47,60 @@ class Influx:
|
||||||
|
|
||||||
# global values
|
# global values
|
||||||
cur_ts = self._timestamp()
|
cur_ts = self._timestamp()
|
||||||
data.append(f'ejabberd s2s_in={self._metrics.get_s2s_in()}i {cur_ts}')
|
data.append(f"ejabberd s2s_in={self._metrics.get_s2s_in()}i {cur_ts}")
|
||||||
data.append(f'ejabberd s2s_out={self._metrics.get_s2s_out()}i {cur_ts}')
|
data.append(f"ejabberd s2s_out={self._metrics.get_s2s_out()}i {cur_ts}")
|
||||||
data.append(f'ejabberd uptime={self._metrics.get_uptime()}i {cur_ts}')
|
data.append(f"ejabberd uptime={self._metrics.get_uptime()}i {cur_ts}")
|
||||||
data.append(f'ejabberd processes={self._metrics.get_processes()}i {cur_ts}')
|
data.append(f"ejabberd processes={self._metrics.get_processes()}i {cur_ts}")
|
||||||
|
|
||||||
# vhost values
|
# vhost values
|
||||||
for vhost in self._metrics.get_vhosts():
|
for vhost in self._metrics.get_vhosts():
|
||||||
cur_ts = self._timestamp()
|
cur_ts = self._timestamp()
|
||||||
data.append(f'ejabberd,vhost={vhost} registered={self._metrics.get_registered(vhost)}i {cur_ts}')
|
data.append(f"ejabberd,vhost={vhost} registered={self._metrics.get_registered(vhost)}i {cur_ts}")
|
||||||
data.append(f'ejabberd,vhost={vhost} muc={self._metrics.get_muc(vhost)}i {cur_ts}')
|
data.append(f"ejabberd,vhost={vhost} muc={self._metrics.get_muc(vhost)}i {cur_ts}")
|
||||||
|
|
||||||
# vhost statistics on their respective node
|
# vhost statistics on their respective node
|
||||||
for node in self._metrics.get_nodes():
|
for node in self._metrics.get_nodes():
|
||||||
cur_ts = self._timestamp()
|
cur_ts = self._timestamp()
|
||||||
for k, v in self._metrics.get_online_by_status(node=node, vhost=vhost).items():
|
for k, v in self._metrics.get_online_by_status(node=node, vhost=vhost).items():
|
||||||
data.append(self._parse('ejabberd_online_status', k, v, cur_ts, {'node': node, 'vhost': vhost}))
|
data.append(self._parse("ejabberd_online_status", k, v, cur_ts, {"node": node, "vhost": vhost}))
|
||||||
for k, v in self._metrics.get_online_by_client(node=node, vhost=vhost).items():
|
for k, v in self._metrics.get_online_by_client(node=node, vhost=vhost).items():
|
||||||
data.append(self._parse('ejabberd_online_client', k, v, cur_ts, {'node': node, 'vhost': vhost}))
|
data.append(self._parse("ejabberd_online_client", k, v, cur_ts, {"node": node, "vhost": vhost}))
|
||||||
for k, v in self._metrics.get_online_by_ipversion(node=node, vhost=vhost).items():
|
for k, v in self._metrics.get_online_by_ipversion(node=node, vhost=vhost).items():
|
||||||
data.append(self._parse('ejabberd_online_ipversion', k, v, cur_ts, {'node': node, 'vhost': vhost}))
|
data.append(self._parse("ejabberd_online_ipversion", k, v, cur_ts, {"node": node, "vhost": vhost}))
|
||||||
for k, v in self._metrics.get_online_by_connection(node=node, vhost=vhost).items():
|
for k, v in self._metrics.get_online_by_connection(node=node, vhost=vhost).items():
|
||||||
data.append(self._parse('ejabberd_online_connection', k, v, cur_ts, {'node': node, 'vhost': vhost}))
|
data.append(self._parse("ejabberd_online_connection", k, v, cur_ts, {"node": node, "vhost": vhost}))
|
||||||
for cl, ipv in self._metrics.get_online_client_by_ipversion(node=node, vhost=vhost).items():
|
for cl, ipv in self._metrics.get_online_client_by_ipversion(node=node, vhost=vhost).items():
|
||||||
for k, v in ipv.items():
|
for k, v in ipv.items():
|
||||||
data.append(self._parse('ejabberd_online_client_ipversion', k, v, cur_ts,
|
data.append(
|
||||||
{'vhost': vhost, 'node': node, 'ipversion': k, 'client': cl}))
|
self._parse(
|
||||||
|
"ejabberd_online_client_ipversion",
|
||||||
|
k,
|
||||||
|
v,
|
||||||
|
cur_ts,
|
||||||
|
{"vhost": vhost, "node": node, "ipversion": k, "client": cl},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# write output to database
|
# write output to database
|
||||||
self.client.write_points(data, time_precision='ms', batch_size=10000, protocol='line')
|
self.client.write_points(data, time_precision="ms", batch_size=10000, protocol="line")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
# load config
|
# load config
|
||||||
config = Config()
|
config = Config()
|
||||||
|
|
||||||
if config.get('debug', default=False):
|
if config.get("debug", default=False):
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
|
||||||
# credentials and parameters
|
# credentials and parameters
|
||||||
url = config.get('url', default='http://localhost:5280/api')
|
url = config.get("url", default="http://localhost:5280/api")
|
||||||
login = config.get('login', default=None)
|
login = config.get("login", default=None)
|
||||||
api = config.get('api', default='rest')
|
api = config.get("api", default="rest")
|
||||||
|
|
||||||
# config influxdb
|
# config influxdb
|
||||||
influx_host = config.get('influxdb_host', default='localhost')
|
influx_host = config.get("influxdb_host", default="localhost")
|
||||||
influx_port = config.get('influxdb_port', default=8086)
|
influx_port = config.get("influxdb_port", default=8086)
|
||||||
influx_dbname = config.get('influxdb_db', default='ejabberd')
|
influx_dbname = config.get("influxdb_db", default="ejabberd")
|
||||||
|
|
||||||
# init handler
|
# init handler
|
||||||
metrics = EjabberdMetrics(url, login, api)
|
metrics = EjabberdMetrics(url, login, api)
|
||||||
|
|
29
metrics.py
29
metrics.py
|
@ -12,7 +12,8 @@ class EjabberdMetrics(EjabberdApiCalls):
|
||||||
"""
|
"""
|
||||||
class to fetch metrics per xmlrpc
|
class to fetch metrics per xmlrpc
|
||||||
"""
|
"""
|
||||||
def __init__(self, url, login=None, api="rpc", muc_host: str = 'conference'):
|
|
||||||
|
def __init__(self, url, login=None, api="rpc", muc_host: str = "conference"):
|
||||||
# init ejabberd api
|
# init ejabberd api
|
||||||
super().__init__(url, login, api)
|
super().__init__(url, login, api)
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ class EjabberdMetrics(EjabberdApiCalls):
|
||||||
"profanity": [],
|
"profanity": [],
|
||||||
"Xabber": ["xabber", "xabber-android"],
|
"Xabber": ["xabber", "xabber-android"],
|
||||||
"ChatSecure": ["chatsecure"],
|
"ChatSecure": ["chatsecure"],
|
||||||
"Monal": []
|
"Monal": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
for client, names in clientmap.items():
|
for client, names in clientmap.items():
|
||||||
|
@ -110,7 +111,7 @@ class EjabberdMetrics(EjabberdApiCalls):
|
||||||
return self.get_online_by("node", vhost=vhost)
|
return self.get_online_by("node", vhost=vhost)
|
||||||
|
|
||||||
def get_online_by_vhost(self, node=None):
|
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)
|
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):
|
def get_online_by_status(self, vhost=None, node=None):
|
||||||
return self.get_online_by("status", vhost=vhost, node=node)
|
return self.get_online_by("status", vhost=vhost, node=node)
|
||||||
|
@ -187,11 +188,11 @@ class EjabberdMetrics(EjabberdApiCalls):
|
||||||
return self._uptime
|
return self._uptime
|
||||||
|
|
||||||
def get_processes(self):
|
def get_processes(self):
|
||||||
if not hasattr(self, '_processes'):
|
if not hasattr(self, "_processes"):
|
||||||
self._processes = self.fetch_processes()
|
self._processes = self.fetch_processes()
|
||||||
return self._processes
|
return self._processes
|
||||||
|
|
||||||
def get_vhost_metrics(self, vhost):
|
def get_vhost_metrics(self, vhost):
|
||||||
data = {
|
data = {
|
||||||
"registered": self.get_registered(vhost),
|
"registered": self.get_registered(vhost),
|
||||||
"muc": self.get_muc(vhost),
|
"muc": self.get_muc(vhost),
|
||||||
|
@ -199,7 +200,7 @@ class EjabberdMetrics(EjabberdApiCalls):
|
||||||
"online_by_client": self.get_online_by_client(vhost),
|
"online_by_client": self.get_online_by_client(vhost),
|
||||||
"online_by_ipversion": self.get_online_by_ipversion(vhost),
|
"online_by_ipversion": self.get_online_by_ipversion(vhost),
|
||||||
"online_by_connection": self.get_online_by_connection(vhost),
|
"online_by_connection": self.get_online_by_connection(vhost),
|
||||||
"online_by_node": self.get_online_by_node(vhost)
|
"online_by_node": self.get_online_by_node(vhost),
|
||||||
}
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
@ -209,13 +210,13 @@ class EjabberdMetrics(EjabberdApiCalls):
|
||||||
self._nodes = self.fetch_nodes()
|
self._nodes = self.fetch_nodes()
|
||||||
return self._nodes
|
return self._nodes
|
||||||
|
|
||||||
def get_node_metrics(self, node):
|
def get_node_metrics(self, node):
|
||||||
data = {
|
data = {
|
||||||
"online_by_status": self.get_online_by_status(node=node),
|
"online_by_status": self.get_online_by_status(node=node),
|
||||||
"online_by_client": self.get_online_by_client(node=node),
|
"online_by_client": self.get_online_by_client(node=node),
|
||||||
"online_by_ipversion": self.get_online_by_ipversion(node=node),
|
"online_by_ipversion": self.get_online_by_ipversion(node=node),
|
||||||
"online_by_connection": self.get_online_by_connection(node=node),
|
"online_by_connection": self.get_online_by_connection(node=node),
|
||||||
"online_by_vhost": self.get_online_by_vhost(node=node)
|
"online_by_vhost": self.get_online_by_vhost(node=node),
|
||||||
}
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
@ -225,7 +226,7 @@ class EjabberdMetrics(EjabberdApiCalls):
|
||||||
"registered": self.get_registered(),
|
"registered": self.get_registered(),
|
||||||
"muc": self.get_muc(),
|
"muc": self.get_muc(),
|
||||||
"s2s_in": self.get_s2s_in(),
|
"s2s_in": self.get_s2s_in(),
|
||||||
"s2s_out": self.get_s2s_out(),
|
"s2s_out": self.get_s2s_out(),
|
||||||
"uptime": self.get_uptime(),
|
"uptime": self.get_uptime(),
|
||||||
"processes": self.get_processes(),
|
"processes": self.get_processes(),
|
||||||
"online_by_status": self.get_online_by_status(),
|
"online_by_status": self.get_online_by_status(),
|
||||||
|
@ -233,14 +234,14 @@ class EjabberdMetrics(EjabberdApiCalls):
|
||||||
"online_by_ipversion": self.get_online_by_ipversion(),
|
"online_by_ipversion": self.get_online_by_ipversion(),
|
||||||
"online_by_connection": self.get_online_by_connection(),
|
"online_by_connection": self.get_online_by_connection(),
|
||||||
"online_by_node": self.get_online_by_node(),
|
"online_by_node": self.get_online_by_node(),
|
||||||
"online_by_vhost": self.get_online_by_vhost()
|
"online_by_vhost": self.get_online_by_vhost(),
|
||||||
}
|
}
|
||||||
|
|
||||||
vhosts = {}
|
vhosts = {}
|
||||||
for host in self.get_vhosts():
|
for host in self.get_vhosts():
|
||||||
vhosts[host] = self.get_vhost_metrics(host)
|
vhosts[host] = self.get_vhost_metrics(host)
|
||||||
data["vhosts"] = vhosts
|
data["vhosts"] = vhosts
|
||||||
|
|
||||||
nodes = {}
|
nodes = {}
|
||||||
for node in self.get_nodes():
|
for node in self.get_nodes():
|
||||||
nodes[node] = self.get_node_metrics(node)
|
nodes[node] = self.get_node_metrics(node)
|
||||||
|
@ -259,9 +260,9 @@ if __name__ == "__main__":
|
||||||
config = Config()
|
config = Config()
|
||||||
|
|
||||||
# credentials and parameters
|
# credentials and parameters
|
||||||
url = config.get('url', default='http://localhost:5280/api')
|
url = config.get("url", default="http://localhost:5280/api")
|
||||||
login = config.get('login', default=None)
|
login = config.get("login", default=None)
|
||||||
api = config.get('api', default='rest')
|
api = config.get("api", default="rest")
|
||||||
|
|
||||||
# init handler
|
# init handler
|
||||||
metrics = EjabberdMetrics(url, login, api)
|
metrics = EjabberdMetrics(url, login, api)
|
||||||
|
|
|
@ -7,9 +7,7 @@ from socket import AF_INET6
|
||||||
from time import time
|
from time import time
|
||||||
from urllib.parse import parse_qs, urlparse
|
from urllib.parse import parse_qs, urlparse
|
||||||
|
|
||||||
from prometheus_client import (
|
from prometheus_client import CollectorRegistry, Gauge, generate_latest, CONTENT_TYPE_LATEST
|
||||||
CollectorRegistry, Gauge, generate_latest, CONTENT_TYPE_LATEST
|
|
||||||
)
|
|
||||||
|
|
||||||
from config import Config
|
from config import Config
|
||||||
from metrics import EjabberdMetrics
|
from metrics import EjabberdMetrics
|
||||||
|
@ -17,26 +15,25 @@ from metrics import EjabberdMetrics
|
||||||
|
|
||||||
class DynamicMetricsHandler(BaseHTTPRequestHandler):
|
class DynamicMetricsHandler(BaseHTTPRequestHandler):
|
||||||
"""HTTP handler that gives metrics from ``core.REGISTRY``."""
|
"""HTTP handler that gives metrics from ``core.REGISTRY``."""
|
||||||
|
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
params = parse_qs(urlparse(self.path).query)
|
params = parse_qs(urlparse(self.path).query)
|
||||||
registry = self.generator(params)
|
registry = self.generator(params)
|
||||||
if 'name[]' in params:
|
if "name[]" in params:
|
||||||
registry = registry.restricted_registry(params['name[]'])
|
registry = registry.restricted_registry(params["name[]"])
|
||||||
try:
|
try:
|
||||||
output = generate_latest(registry)
|
output = generate_latest(registry)
|
||||||
except:
|
except:
|
||||||
self.send_error(500, 'error generating metric output')
|
self.send_error(500, "error generating metric output")
|
||||||
raise
|
raise
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header('Content-Type', CONTENT_TYPE_LATEST)
|
self.send_header("Content-Type", CONTENT_TYPE_LATEST)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(output)
|
self.wfile.write(output)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def factory(registry_generator):
|
def factory(registry_generator):
|
||||||
DynMetricsHandler = type('MetricsHandler',
|
DynMetricsHandler = type("MetricsHandler", (DynamicMetricsHandler, object), {"generator": registry_generator})
|
||||||
(DynamicMetricsHandler, object),
|
|
||||||
{"generator": registry_generator})
|
|
||||||
return DynMetricsHandler
|
return DynMetricsHandler
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +42,7 @@ class Prometheus:
|
||||||
self.ttl = 10
|
self.ttl = 10
|
||||||
self._last_update = 0
|
self._last_update = 0
|
||||||
self._metrics = metrics
|
self._metrics = metrics
|
||||||
|
|
||||||
def handler(self, metrics_handler):
|
def handler(self, metrics_handler):
|
||||||
now = time()
|
now = time()
|
||||||
if now >= (self._last_update + self.ttl):
|
if now >= (self._last_update + self.ttl):
|
||||||
|
@ -54,25 +51,53 @@ class Prometheus:
|
||||||
|
|
||||||
registry = CollectorRegistry(auto_describe=True)
|
registry = CollectorRegistry(auto_describe=True)
|
||||||
|
|
||||||
Gauge('ejabberd_node_s2s_in', 'count of incoming server-to-server connection', registry=registry).set(self._metrics.get_s2s_in())
|
Gauge("ejabberd_node_s2s_in", "count of incoming server-to-server connection", registry=registry).set(
|
||||||
Gauge('ejabberd_node_s2s_out', 'count of outgoing server-to-server connection', registry=registry).set(self._metrics.get_s2s_out())
|
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()
|
||||||
|
)
|
||||||
|
|
||||||
nodename = self._metrics.nodename
|
nodename = self._metrics.nodename
|
||||||
Gauge('ejabberd_node_uptime', 'uptime of ejabberd service', ["node"], registry=registry).labels(nodename).set(self._metrics.get_uptime())
|
Gauge("ejabberd_node_uptime", "uptime of ejabberd service", ["node"], registry=registry).labels(nodename).set(
|
||||||
Gauge('ejabberd_node_proccess', 'count of pejabber proccess', ["node"], registry=registry).labels(nodename).set(self._metrics.get_processes())
|
self._metrics.get_uptime()
|
||||||
|
)
|
||||||
|
Gauge("ejabberd_node_proccess", "count of pejabber proccess", ["node"], registry=registry).labels(nodename).set(
|
||||||
|
self._metrics.get_processes()
|
||||||
|
)
|
||||||
|
|
||||||
labelnames_vhost = ["vhost"]
|
labelnames_vhost = ["vhost"]
|
||||||
|
|
||||||
registered_vhosts = Gauge('ejabberd_registered_vhosts', 'count of user per vhost', labelnames_vhost, registry=registry)
|
registered_vhosts = Gauge(
|
||||||
muc = Gauge('ejabberd_muc', 'count of muc\'s per vhost', labelnames_vhost, registry=registry)
|
"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_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_status = Gauge(
|
||||||
online_ipversion = Gauge('ejabberd_online_ipversion', 'count of client software', ["vhost", "node", "ipversion"], registry=registry)
|
"ejabberd_online_status", "count of client connections", ["vhost", "node", "status"], registry=registry
|
||||||
online_client_ipversion = Gauge('ejabberd_online_client_ipversion', 'count of client software', ["vhost", "node", "client", "ipversion"], 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,
|
||||||
|
)
|
||||||
|
|
||||||
for host in self._metrics.get_vhosts():
|
for host in self._metrics.get_vhosts():
|
||||||
labels_vhost = host
|
labels_vhost = host
|
||||||
|
@ -108,19 +133,19 @@ class Prometheus:
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# load config
|
# load config
|
||||||
config = Config()
|
config = Config()
|
||||||
if config.get('debug', default=False):
|
if config.get("debug", default=False):
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
|
||||||
# credentials and parameters
|
# credentials and parameters
|
||||||
url = config.get('url', default='http://[::1]:5280/api')
|
url = config.get("url", default="http://[::1]:5280/api")
|
||||||
login = config.get('login', default=None)
|
login = config.get("login", default=None)
|
||||||
api = config.get('api', default='rest')
|
api = config.get("api", default="rest")
|
||||||
|
|
||||||
# config prometheus
|
# config prometheus
|
||||||
prom_addr = config.get('prometheus_address', default='127.0.0.1')
|
prom_addr = config.get("prometheus_address", default="127.0.0.1")
|
||||||
prom_port = config.get('prometheus_port', default=8080)
|
prom_port = config.get("prometheus_port", default=8080)
|
||||||
|
|
||||||
metrics = EjabberdMetrics(url, login, api)
|
metrics = EjabberdMetrics(url, login, api)
|
||||||
prom = Prometheus(metrics)
|
prom = Prometheus(metrics)
|
||||||
prom.ttl = config.get('prometheus_cache_ttl', default=10)
|
prom.ttl = config.get("prometheus_cache_ttl", default=10)
|
||||||
prom.listen((prom_addr, prom_port))
|
prom.listen((prom_addr, prom_port))
|
||||||
|
|
Loading…
Reference in New Issue