#!/usr/bin/env python3 import subprocess import json import sys import hashlib import logging from urllib.parse import urljoin from lxml import etree import requests def error(msg): print(msg, file=sys.stderr) sys.exit(2) def get_conf(): secret, base_url = "", "" out = subprocess.check_output(["bbb-conf", "--secret"]) for line in out.splitlines(): line = line.strip().decode('utf-8') if line.lower().startswith('url:'): base_url = line[len('url: '):] if line.lower().startswith('secret:'): secret = line[len('secret: '):] return secret, base_url + 'api/' def checksum(secret, baseurl, endpoint): content = endpoint + secret sha1 = hashlib.sha1() sha1.update(content.encode('utf-8')) return sha1.hexdigest() def get(baseurl, endpoint, secret): url = urljoin(baseurl, endpoint + '?checksum=' + checksum(secret, baseurl, endpoint)) try: res = requests.get(url) except Exception: logging.exception('fail to make api call') return os.exit(2) return etree.fromstring(res.text) def dump_meetings(baseurl, secret): t = get(baseurl, 'getMeetings', secret) meetings = t.findall('.//meeting') metrics = { 'meetings': len(meetings), 'inactive_meetings': 0, 'participants': 0, 'voice_participants': 0, 'video_participants': 0, 'listeners': 0 } for node in meetings: participants = int(node.find('participantCount').text) voice_participants = int(node.find('voiceParticipantCount').text) video_participants = int(node.find('videoCount').text) listeners = int(node.find('listenerCount').text) metrics['participants'] += participants metrics['voice_participants'] += voice_participants metrics['video_participants'] += video_participants metrics['listeners'] += listeners if participants == 0: metrics['inactive_meetings'] += 1 return metrics def dump_recordings(baseurl, secret): t = get(baseurl, 'getRecordings', secret) metrics = {'processing_recordings': 0, 'processed_recordings': 0, 'published_recordings': 0, 'unpublished_recordings': 0} for node in t.findall('.//recording'): origstate = node.find('state').text state = origstate + '_recordings' if state not in metrics: return error('unknown state `%s`' % origstate) metrics[state] += 1 return metrics def main(): secret, baseurl = get_conf() metrics = {} metrics.update(dump_recordings(baseurl, secret)) metrics.update(dump_meetings(baseurl, secret)) print(json.dumps(metrics)) main()