diff --git a/plugins/prosody/prosody_0.12_ b/plugins/prosody/prosody_0.12_ new file mode 100755 index 00000000..6f7c29d0 --- /dev/null +++ b/plugins/prosody/prosody_0.12_ @@ -0,0 +1,289 @@ +#!/usr/bin/env python3 +""" +=head1 NAME + +prosody_0.12_ - Munin wildcard-plugin to monitor a L XMPP server. + +This wildcard plugin provides at the moment only the suffixes C, C, C, +C and C suffixes. + +=head1 INSTALLATION + +- Copy this plugin in your munin plugins directory +- Rename it prosody_ + +=over 2 + + ln -s /usr/share/munin/plugins/prosody_ /etc/munin/plugins/prosody_c2s + ln -s /usr/share/munin/plugins/prosody_ /etc/munin/plugins/prosody_s2s + ln -s /usr/share/munin/plugins/prosody_ /etc/munin/plugins/prosody_presence + ln -s /usr/share/munin/plugins/prosody_ /etc/munin/plugins/prosody_uptime + ln -s /usr/share/munin/plugins/prosody_ /etc/munin/plugins/prosody_users + +=back + +After the installation you need to restart your munin-node service. + +=head1 CONFIGURATION + +You can create a file named prosody placed in the directory +/etc/munin/plugin-conf.d/ with the following config: + +=over 2 + + [prosody_*] + env.host example.com + env.port 5582 + +=back + +=head1 AUTHORS + +Codimp + +=head1 LICENSE + +GPLv3 + +=head1 MAGIC MARKERS + + #%# family=manual + #%# capabilities=suggest + +=cut +""" + +import sys +import os +import telnetlib +import re + +def create_table(table, start_pattern, end_pattern): + start = table.find(start_pattern) + end = table.find(end_pattern, start + 1) + return table[start:end].splitlines()[1:-1] + +def format_c2s_connections(c2s_table): + connections = [] + for line in c2s_table: + line = line.split('|') + connection = {} + connection['session_id'] = line[1].strip() + connection['jid'] = line[2].strip() + connection['ip_type'] = line[3].strip() + connection['status'] = line[4].strip() + connection['security'] = line[5].strip() + connection['sm'] = line[6].strip() + connection['csi_state'] = line[7].strip() + connections.append(connection) + return connections + +def count_c2s_connections(connections): + secure_connections = 0 + insecure_connections = 0 + for connection in connections: + if connection['security'] == 'insecure': + insecure_connections += 1 + else: + secure_connections += 1 + return (secure_connections, insecure_connections) + +def format_s2s_connections(s2s_table): + connections = [] + for line in s2s_table: + line = line.split('|') + connection = {} + connection['session_id'] = line[1].strip() + connection['host'] = line[2].strip() + connection['direction'] = line[3].strip() + connection['remote'] = line[4].strip() + connection['ip_type'] = line[5].strip() + connection['security'] = line[6].strip() + connection['sasl'] = line[7].strip() + connection['dialback'] = line[8].strip() + connections.append(connection) + return connections + +def count_s2s_connections(connections): + incoming_pattern = '<--' + outgoing_pattern = '-->' + incoming_connections = 0 + outgoing_connections = 0 + for connection in connections: + if connection['direction'] == incoming_pattern: + incoming_connections += 1 + elif connection['direction'] == outgoing_pattern: + outgoing_connections += 1 + return (incoming_connections, outgoing_connections) + +def count_presences(connections): + available = 0 + chat = 0 + away = 0 + xa = 0 + dnd = 0 + for presence in connections: + if presence['status'] == 'online': + available += 1 + elif presence['status'] == 'chat': + chat += 1 + elif presence['status'] == 'away': + away += 1 + elif presence['status'] == 'xa': + xa += 1 + elif presence['status'] == 'dnd': + dnd += 1 + return (available, chat, away, xa, dnd) + +def format_hosts(host_table): + hosts = [] + for line in host_table: + host = line.strip('| ') + if '(' not in host: + hosts.append(host) + return hosts[1:] + +def main(): + try: + mode = sys.argv[1] + except IndexError: + mode = "" + wildcard = sys.argv[0].split("prosody_")[1].split("_")[0] + host = os.environ.get('host', 'localhost') + port = int(os.environ.get('port', 5582)) + + if mode == "suggest": + print("c2s") + print("s2s") + print("presence") + print("uptime") + print("users") + sys.exit(0) + + if wildcard == "c2s": + if mode == "config": + print("graph_title Prosody C2S Connections") + print("graph_vlabel users") + print("graph_category chat") + print("all_client_connections.label client connections") + print("secure_client_connections.label secure client connections") + print("insecure_client_connections.label insecure client connections") + sys.exit(0) + else: + telnet = telnetlib.Telnet(host, port) + telnet.write(b"c2s:show()\n") + telnet_response = telnet.read_until(b"| OK:", 5) + telnet_response = telnet_response.decode() + telnet.write(b"quit\n") + # Select table lines + c2s_table = create_table(telnet_response, "Session ID", "c2s sessions") + # Format, count and print result + connections = format_c2s_connections(c2s_table) + secure_client_connections, insecure_client_connections = count_c2s_connections(connections) + all_client_connections = secure_client_connections + insecure_client_connections + print("all_client_connections.value %s" % (all_client_connections)) + print("secure_client_connections.value %s" % secure_client_connections) + print("insecure_client_connections.value %s" % insecure_client_connections) + + elif wildcard == "s2s": + if mode == "config": + print("graph_title Prosody S2S Connections") + print("graph_vlabel servers") + print("graph_category chat") + print("outgoing_connections.label outgoing connections") + print("incoming_connections.label incoming connections") + sys.exit(0) + else: + telnet = telnetlib.Telnet(host, port) + telnet.write(b"s2s:show()\n") + telnet_response = telnet.read_until(b"| OK:", 5) + telnet_response = telnet_response.decode() + telnet.write(b"quit\n") + # Select table lines + s2s_table = create_table(telnet_response, "Session ID", "s2s connections") + # Format, count and print result + connections = format_s2s_connections(s2s_table) + incoming_connections, outgoing_connections = count_s2s_connections(connections) + print("outgoing_connections.value %s" % (outgoing_connections)) + print("incoming_connections.value %s" % (incoming_connections)) + + elif wildcard == "presence": + if mode == "config": + print("graph_title Prosody Client Presence") + print("graph_vlabel clients") + print("graph_category chat") + print("available.label Available Clients") + print("chat.label Ready for Chat Clients") + print("away.label Away Clients") + print("xa.label Extended Away Clients") + print("dnd.label Do Not Disturb Clients") + sys.exit(0) + else: + telnet = telnetlib.Telnet(host, port) + telnet.write(b"c2s:show()\n") + telnet_response = telnet.read_until(b"| OK:", 5) + telnet_response = telnet_response.decode() + telnet.write(b"quit\n") + # Select table lines + c2s_table = create_table(telnet_response, "Session ID", "c2s sessions") + # Format, count and print result + connections = format_c2s_connections(c2s_table) + available, chat, away, xa, dnd = count_presences(connections) + print("available.value %s" % available) + print("chat.value %s" % chat) + print("away.value %s" % away) + print("xa.value %s" % xa) + print("dnd.value %s" % dnd) + + elif wildcard == "uptime": + if mode == "config": + print("graph_title Prosody Uptime") + print("graph_args --base 1000 -l 0") + print("graph_scale no") + print("graph_vlabel uptime in days") + print("graph_category chat") + print("graph_order uptime") + print("uptime.draw AREA") + print("uptime.min U") + print("uptime.max U") + print("uptime.label uptime") + print("uptime.type GAUGE") + sys.exit(0) + else: + uptime_re = re.compile(r"\d+") + telnet = telnetlib.Telnet(host, port) + telnet.write(b"server:uptime()\n") + telnet_response = telnet.read_until(b"minutes (", 5) + telnet.write(b"quit\n") + parsed_info = uptime_re.findall(telnet_response.decode()) + uptime_value = (float(parsed_info[0]) + float(parsed_info[1]) / 24 + + float(parsed_info[2]) / 60 / 24) + print("uptime.value %s" % (uptime_value)) + + elif wildcard == "users": + if mode == "config": + print("graph_title Prosody Registered Users") + print("graph_vlabel users") + print("graph_category chat") + else: + telnet = telnetlib.Telnet(host, port) + # Get host list + telnet.write(b"host:list()\n") + telnet_response = telnet.read_until(b"| OK:", 5) + telnet_response = telnet_response.decode() + host_table = create_table(telnet_response, "| https://prosody.im/doc/console", "| OK: ") + hosts = format_hosts(host_table) + # Get user list + for host in hosts: + telnet.write(b"user:list('" + host.encode() + b"')\n") + telnet_response = telnet.read_until(b"users", 5) + telnet_response = telnet_response.decode() + user_re = re.compile(r"\d+ users") + parsed_info = user_re.findall(telnet_response) + users = parsed_info[0].strip(' users') + print("%s.value %s" % (host, users)) + telnet.write(b"quit\n") + + +if __name__ == "__main__": + main()