diff --git a/.gitignore b/.gitignore index 238eac72a23728c6eae8251a73a06750d0e40d6c..bc8e2760177de08e7cd585a29067c5b7e3fa3a2e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .idea/ -venv/ \ No newline at end of file +venv/ +config.ini +__pycache__/ diff --git a/example_config.ini b/example_config.ini new file mode 100644 index 0000000000000000000000000000000000000000..372a454edcc027bb3421fbe6006385622a3f1fdb --- /dev/null +++ b/example_config.ini @@ -0,0 +1,4 @@ +BIND_ADDR = :: +PORT = 8337 +SYNAPSE_URL = +ACCESS_TOKEN = \ No newline at end of file diff --git a/exporter.py b/exporter.py index 6a80909eb5a9b1ef1c9bf43b4a2c99b6702b1d0c..1863b63aba907f9e586189ae44f75644de5331de 100755 --- a/exporter.py +++ b/exporter.py @@ -1,76 +1,90 @@ #! /usr/bin/env python -import os - import requests from prometheus_client import start_http_server, Gauge from time import sleep +import argparse metric_members = Gauge('matrix_channel_members_total', 'Members joined in room', ['room_id', 'canonical_alias', 'name']) metric_channel_types = Gauge('matrix_channel_types_total', 'Channels per type', ['type']) metric_channel_version = Gauge('matrix_channel_version_total', 'Channels per version', ['version']) -metric_channel_state_events = Gauge('matrix_channel_state_events_total', 'State events per room', ['room_id', 'canonical_alias', 'name']) +metric_channel_state_events = Gauge('matrix_channel_state_events_total', 'State events per room', + ['room_id', 'canonical_alias', 'name']) + + +def fetch_metrics(synapse_url, access_token): + room_type_count = { + 'space': 0, + 'public': 0, + 'private': 0, + 'dm': 0 + } + room_version_count = {} + + auth = { + 'Authorization': f"Bearer {access_token}" + } + + rooms = requests.get(f"https://{synapse_url}/_synapse/admin/v1/rooms", headers=auth).json()['rooms'] + + for room in rooms: + if room['version'] not in room_version_count: + room_version_count[room['version']] = 0 + room_version_count[room['version']] += 1 -def fetch_metrics(): - room_type_count = { - 'space': 0, - 'public': 0, - 'private': 0, - 'dm': 0 - } + if room['room_type'] == 'm.space': + room_type_count['space'] += 1 + elif room['join_rules'] == 'public': + room_type_count['public'] += 1 + elif room['name'] and room['join_rules'] == 'invite': + room_type_count['private'] += 1 + else: + room_type_count['dm'] += 1 - auth = { - 'Authorization': f"Bearer {config['token']}" - } - room_version_count = {} - rooms = requests.get(f"https://{config['synapse_url']}/_synapse/admin/v1/rooms", headers=auth).json()['rooms'] + metric_members.labels( + room_id=room['room_id'], + canonical_alias=room['canonical_alias'] if room['canonical_alias'] else '', + name=room['name'] if room['name'] else '' + ).set(room['joined_members']) - for room in sorted(rooms, key=lambda item: item['joined_members'], reverse=True): - if room['version'] not in room_version_count: - room_version_count[room['version']] = 0 + metric_channel_state_events.labels( + room_id=room['room_id'], + canonical_alias=room['canonical_alias'] if room['canonical_alias'] else '', + name=room['name'] if room['name'] else '' + ).set(room['state_events']) - room_version_count[room['version']] += 1 + for room_version, count in room_version_count.items(): + metric_channel_version.labels(version=room_version).set(count) - if room['room_type'] == 'm.space': - room_type_count['space'] += 1 - elif room['join_rules'] == 'public': - room_type_count['public'] += 1 - elif room['name'] and room['join_rules'] == 'invite': - room_type_count['private'] += 1 - else: - room_type_count['dm'] += 1 + for room_type, count in room_type_count.items(): + metric_channel_types.labels(type=room_type).set(count) - metric_members.labels( - room_id=room['room_id'], - canonical_alias=room['canonical_alias'] if room['canonical_alias'] else '', - name=room['name'] if room['name'] else '' - ).set(room['joined_members']) - metric_channel_state_events.labels( - room_id=room['room_id'], - canonical_alias=room['canonical_alias'] if room['canonical_alias'] else '', - name=room['name'] if room['name'] else '' - ).set(room['state_events']) +def parse_config(config): + config_parsed = {} + for line in config.splitlines(): + if not line.startswith('#') and len(line) > 0: + parts = line.split('=', 1) - for room_version, count in room_version_count.items(): - metric_channel_version.labels(version=room_version).set(count) + config_parsed[parts[0].strip()] = parts[1].strip() - for room_type, count in room_type_count.items(): - metric_channel_types.labels(type=room_type).set(count) + return config_parsed if __name__ == '__main__': - config = { - 'port': int(os.environ.get('PORT')), - 'token': os.environ.get('ACCESS_TOKEN'), - 'synapse_url': os.environ.get('SYNAPSE_URL') - } - - start_http_server(config['port'], addr='::') - - while True: - try: - fetch_metrics() - except Exception as e: - print('Exception:\n' + str(e)) - sleep(20) + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--config', + default='config.ini', + type=argparse.FileType('r')) + + args = parser.parse_args() + config = parse_config(args.config.read()) + + start_http_server(int(config['PORT']), addr=config['BIND_ADDR']) + + while True: + try: + fetch_metrics(config['SYNAPSE_URL'], config['ACCESS_TOKEN']) + except Exception as e: + print('Exception:\n' + str(e)) + sleep(20) diff --git a/requirements.txt b/requirements.txt index d19079c8311ac47fffab869ec349a968601e570b..b96cc428315d5b83d685d2d465a7bc16886b4892 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ requests -prometheus-client \ No newline at end of file +prometheus-client +argparse \ No newline at end of file