From cf9a6da4dfa21d1eb919e1232af76bd48aa72cac Mon Sep 17 00:00:00 2001 From: "Sebastian L." Date: Tue, 6 Feb 2024 15:51:33 +0100 Subject: [PATCH] [synapse_]: A simple wildcard plugin for synapse matrix homeserver Y --- plugins/synapse/synapse_ | 214 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 plugins/synapse/synapse_ diff --git a/plugins/synapse/synapse_ b/plugins/synapse/synapse_ new file mode 100644 index 00000000..46d79981 --- /dev/null +++ b/plugins/synapse/synapse_ @@ -0,0 +1,214 @@ +#!/usr/bin/env sh +# shellcheck shell=dash + +set -e + +: << =cut + +=head1 NAME + +synapse_ - Monitor synapse matrix homeserver over admin API + +=head1 APPLICABLE SYSTEMS + +Synapse matrix homeserver + +=head1 CONFIGURATION + +Requires installed curl and jq, a command-line json processor. + +This is a wildcard plugin. It monitors some simple values over the admin API +of synapse matrix homeserver. Link synapse_ to this file. The +admin endpoint has to be reachable from the plugin. + + ln -s /usr/share/munin/plugins/synapse_ \ + /etc/munin/plugins/synapse_domain.tld + +Set parameters in your munin-node configuration + + [synapse_homeserverurl] + env.auth_token + env.interval + env.port + env.admin_api_path + env.scheme + env.timeout + env.reports_warning + +To monitor a synapse instance on localhost you need following: + + ln -s /usr/share/munin/plugins/synapse_ \ + /etc/munin/plugins/synapse_localhost + + [synapse_localhost] + env.auth_token + env.port 8008 + env.scheme http + +It's advised to use a dedicated munin bot account (user_type bot) with admin +rights on your matrix synapse server for this plugin. + +=head1 AUTHOR + +Copyright (C) 2024 Sebastian L. (https://momou.ch), + +=head1 LICENSE + +GPLv2 + +=head1 MAGIC MARKERS + + #%# family=manual + #%# capabilities=autoconf + +=cut + +# shellcheck disable=SC1090 +. "$MUNIN_LIBDIR/plugins/plugin.sh" + +if [ "${MUNIN_DEBUG:-0}" = 1 ]; then + set -x +fi + +AUTH_TOKEN="${auth_token:-}" +INTERVAL="${interval:-300}" +PORT="${port:-443}" +ADMIN_API_PATH="${admin_api_path:-/_synapse/admin}" +QUERY_LIMIT="${query_limit:-1000}" +HOMESERVER="${0##*synapse_}" +SCHEME="${scheme:-https}://" +TIMEOUT="${timeout:-2}" +REPORTS_WARNING="${reports_warning:-1}" +CLEANHOMESERVER="$(clean_fieldname "${HOMESERVER}")" + +fetch_url () { + curl -s -f -m "${TIMEOUT}" "$@" +} + +case $1 in + + autoconf) + if [ ! -x "$(command -v curl)" ]; then + echo "no (curl not found)" + elif [ ! -x "$(command -v jq)" ]; then + echo "no (jq not found)" + else + fetch_url -I -H "Authorization: Bearer ${AUTH_TOKEN}" -I "${SCHEME}${HOMESERVER}:${PORT}${ADMIN_API_PATH}" \ + | grep -iq "Content-Type: application/json" \ + && echo "yes" \ + || echo "no (invalid or empty response from synapse admin api)" + fi + exit 0 + ;; + config) + +cat << EOM +multigraph synapse_users_${CLEANHOMESERVER} +graph_title Synapse users on ${HOMESERVER} +graph_args --base 1000 -l 0 +graph_printf %.0lf +graph_vlabel users +graph_info users +graph_category chat +total_registered.label total registered users +total_registered.info total registered users +total_registered.min 0 +active_users.label active users +active_users.info active users +active_users.min 0 +online_users.label online users +online_users.info online users +online_users.min 0 +online_users.draw LINE2 +deactivated_users.label deactivated users +deactivated_users.info deactivated users +deactivated_users.min 0 +erased_users.label erased users +erased_users.info erased users +erased_users.min 0 +multigraph synapse_rooms_${CLEANHOMESERVER} +graph_title Synapse spaces and rooms on ${HOMESERVER} +graph_args --base 1000 -l 0 +graph_printf %.0lf +graph_vlabel rooms +graph_info rooms +graph_category chat +rooms_local.draw AREASTACK +rooms_local.label rooms on ${HOMESERVER} +rooms_local.info rooms on ${HOMESERVER} +rooms_local.min 0 +rooms_external.draw AREASTACK +rooms_external.label external rooms +rooms_external.info external rooms +rooms_external.min 0 +spaces.label spaces +spaces.info spaces +spaces.min 0 +rooms_total.label total rooms +rooms_total.info total rooms +rooms_total.min 0 +rooms_total.draw LINE2 +multigraph synapse_reports_${CLEANHOMESERVER} +graph_title Synapse event reports on ${HOMESERVER} +graph_args --base 1000 -l 0 +graph_printf %.0lf +graph_vlabel reports +graph_info reports +graph_category chat +event_reports.label reports +event_reports.info reports +event_reports.min 0 +event_reports.warning ${REPORTS_WARNING} +EOM + exit 0 + ;; + +esac + +USERS=$(fetch_url -H "Authorization: Bearer ${AUTH_TOKEN}" "${SCHEME}${HOMESERVER}:${PORT}${ADMIN_API_PATH}/v2/users?deactivated=true¬_user_type=bot&limit=${QUERY_LIMIT}") +ROOMS=$(fetch_url -H "Authorization: Bearer ${AUTH_TOKEN}" "${SCHEME}${HOMESERVER}:${PORT}${ADMIN_API_PATH}/v1/rooms?limit=${QUERY_LIMIT}") +REPORTS=$(fetch_url -H "Authorization: Bearer ${AUTH_TOKEN}" "${SCHEME}${HOMESERVER}:${PORT}${ADMIN_API_PATH}/v1/event_reports" | jq .total) + +echo multigraph synapse_users_"${CLEANHOMESERVER}" +if USERS="$(echo "$USERS" | jq -r)"; then + echo total_registered.value "$(echo "$USERS" | jq -r .total)" + echo active_users.value "$(echo "$USERS" | grep -c '"deactivated": 0')" + # Convert to miliseconds + time_ms=$(($(date +%s) * 1000)) + interval_ms=$((INTERVAL * 1000)) + time_interval_ago=$(( time_ms - interval_ms )) + last_seen_times_ms=$(echo "$USERS" | grep -E "\"last_seen_ts\": [0-9]+") + echo online_users.value "$(echo "$last_seen_times_ms" | awk -v "count=0" -F": " '$2 > "'$time_interval_ago'" {count++} END {print count}')" + echo deactivated_users.value "$(echo "$USERS" | grep -c '"deactivated": 1')" + echo erased_users.value "$(echo "$USERS" | grep -c '"erased": true')" +else + echo "total_registered.value U" + echo "active_users.value U" + echo "online_users.value U" + echo "deactivated_users.value U" + echo "erased_users.value U" +fi + +echo multigraph synapse_rooms_"${CLEANHOMESERVER}" +if ROOMS="$(echo "$ROOMS" | jq -r)"; then + total_rooms="$(echo "$ROOMS" | jq -r .total_rooms)" + rooms_local="$(echo "$ROOMS" | grep -cE "\"room_id\": \"\!.+:${HOMESERVER}\"")" + rooms_external=$(( total_rooms - rooms_local )) + echo rooms_local.value "$rooms_local" + echo rooms_external.value "$rooms_external" + echo spaces.value "$(echo "$ROOMS" | grep -c '"room_type": "m.space"')" + echo rooms_total.value "$total_rooms" +else + echo "rooms_local.value U" + echo "rooms_external.value U" + echo "spaces.value U" + echo "rooms_total.value U" +fi +echo multigraph synapse_reports_"${CLEANHOMESERVER}" +if [ "$REPORTS" -eq "$REPORTS" ]; then + echo event_reports.value "$REPORTS" +else + echo "event_reports.value U" +fi + +