diff --git a/.gitignore b/.gitignore index bc8e2760177de08e7cd585a29067c5b7e3fa3a2e..b0989bf82f8fcd3f68d68dc36cac1302a9bcffcc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ venv/ config.ini __pycache__/ +state/ diff --git a/exporter.py b/exporter.py index c1dec1a2d4e950c5f9ff84d0b5a3ae844756fea6..9c97c0e77d6d86f0b127cbcdb3d2390ddf49caa1 100755 --- a/exporter.py +++ b/exporter.py @@ -1,6 +1,6 @@ #! /usr/bin/env python import requests -from prometheus_client import start_http_server, Gauge +from prometheus_client import start_http_server, Counter, Gauge from time import sleep import argparse @@ -9,9 +9,57 @@ metric_channel_types = Gauge('matrix_channel_types_total', 'Channels per 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_messages = Counter('matrix_channel_messages_total', 'Messages per channel', ['room_id', 'canonical_alias', 'name', 'type']) def fetch_metrics(synapse_url, access_token): + auth = { + 'Authorization': f"Bearer {access_token}" + } + + rooms = requests.get(f"{synapse_url}/_synapse/admin/v1/rooms", headers=auth).json()['rooms'] + + update_room_metrics(rooms) + + for room in rooms: + statefile = f'state/{room['room_id']}.end' + url = f"{synapse_url}/_synapse/admin/v1/rooms/{room['room_id']}/messages" + messages = [] + + end = None + try: + with open(statefile, 'r') as file: + end = file.read() + except OSError: + print(f"No state file for room {room['room_id']} found. Fetching messages could take a while.") + + while True: + params = {} + if end is not None: + params['from'] = end + + result = requests.get(url, params=params, headers=auth).json() + + if 'chunk' in result and len(result['chunk']): + messages.extend(result['chunk']) + + if 'end' in result: + end = result['end'] + else: + break + + for message in messages: + metric_channel_messages.labels( + room_id=room['room_id'], + canonical_alias=room['canonical_alias'] if room['canonical_alias'] else '', + name=room['name'] if room['name'] else '', + type=message['type']).inc() + + with open(statefile, 'w') as file: + file.write(end) + + +def update_room_metrics(rooms): room_type_count = { 'space': 0, 'public': 0, @@ -20,12 +68,6 @@ def fetch_metrics(synapse_url, access_token): } room_version_count = {} - auth = { - 'Authorization': f"Bearer {access_token}" - } - - rooms = requests.get(f"{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