mirror of
https://github.com/munin-monitoring/contrib.git
synced 2025-07-21 10:39:53 +00:00
[synapse_]: Allow disabling users check
[mas_]: Add plugin to check users on a matrix authentication service (currently only for matrix synapse)
This commit is contained in:
parent
2157586c7f
commit
4c6df3d282
2 changed files with 223 additions and 37 deletions
169
plugins/synapse/mas_
Normal file
169
plugins/synapse/mas_
Normal file
|
@ -0,0 +1,169 @@
|
|||
#!/usr/bin/env sh
|
||||
# shellcheck shell=dash
|
||||
|
||||
set -e
|
||||
|
||||
: << =cut
|
||||
|
||||
=head1 NAME
|
||||
|
||||
mas_ - Monitor users on a matrix authentication service over admin API
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Matrix authentication service (currently only with matrix-synapse systems)
|
||||
|
||||
=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 matrix authentication service. Link mas_<masurl> to this file. The admin
|
||||
endpoint has to be reachable from the plugin. The adminapi endpoint on the
|
||||
matrix authentication service has to be enabled and a client (with client_id
|
||||
and client_id) has to be configured accordingly.
|
||||
|
||||
ln -s /usr/share/munin/plugins/mas_ \
|
||||
/etc/munin/plugins/mas_domain.tld
|
||||
|
||||
Set parameters in your munin-node configuration
|
||||
|
||||
[mas_masurl]
|
||||
env.client_id <client_id>
|
||||
env.client_secret <client_secret>
|
||||
env.bot_names <list of bot names>
|
||||
env.port <port>
|
||||
env.scheme <default: https>
|
||||
env.timeout <default: 2s>
|
||||
|
||||
To monitor a matrix authentication service instance on localhost you need
|
||||
following:
|
||||
|
||||
ln -s /usr/share/munin/plugins/mas_ \
|
||||
/etc/munin/plugins/mas_localhost
|
||||
|
||||
[mas_localhost]
|
||||
env.client_id <client_id>
|
||||
env.client_secret <client_secret>
|
||||
env.port 8081
|
||||
env.scheme http
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright (C) 2025 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
|
||||
|
||||
CLIENT_ID="${client_id:-}"
|
||||
CLIENT_SECRET="${client_secret:-}"
|
||||
PORT="${port:-443}"
|
||||
QUERY_LIMIT="${query_limit:-10000}"
|
||||
MASSERVER="${0##*mas_}"
|
||||
SCHEME="${scheme:-https}://"
|
||||
TIMEOUT="${timeout:-2}"
|
||||
CLEANMASSERVER="$(clean_fieldname "${MASSERVER}")"
|
||||
|
||||
get_access_token () {
|
||||
ACCESS_TOKEN=$(curl -s -f -m "${TIMEOUT}" -u "$CLIENT_ID:$CLIENT_SECRET" -d "grant_type=client_credentials&scope=urn:mas:admin" "${SCHEME}${MASSERVER}/oauth2/token" | jq -r '.access_token')
|
||||
}
|
||||
|
||||
fetch_url () {
|
||||
get_access_token
|
||||
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
|
||||
get_access_token
|
||||
fetch_url -I -H "Authorization: Bearer ${ACCESS_TOKEN}" -I "${SCHEME}${MASSERVER}:${PORT}/api/admin/v1/users" \
|
||||
| grep -iq "Content-Type: application/json" \
|
||||
&& echo "yes" \
|
||||
|| echo "no (invalid or empty response from matrix authentication service admin api)"
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
config)
|
||||
|
||||
cat << EOM
|
||||
multigraph mas_users_${CLEANMASSERVER}
|
||||
graph_title Users on ${MASSERVER} (matrix authentication service)
|
||||
graph_args --base 1000 -l 0
|
||||
graph_printf %.0lf
|
||||
graph_vlabel users
|
||||
graph_info users
|
||||
graph_category chat
|
||||
registered.label registered users
|
||||
registered.info registered users
|
||||
registered.min 0
|
||||
active.label active users
|
||||
active.info active users
|
||||
active.min 0
|
||||
bots.label active bots
|
||||
bots.info active bots
|
||||
bots.min 0
|
||||
deactivated.label deactivated users
|
||||
deactivated.info deactivated users
|
||||
deactivated.min 0
|
||||
sessions.label user sessions
|
||||
sessions.info user sessions
|
||||
sessions.min 0
|
||||
sessions.draw LINE2
|
||||
EOM
|
||||
exit 0
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
mktemp_command="${mktemp_command:-/usr/bin/mktemp}"
|
||||
USERS_FILE=$($mktemp_command) || exit 73
|
||||
trap 'rm -f "$USERS_FILE"' EXIT
|
||||
|
||||
get_access_token
|
||||
fetch_url -g -H "Authorization: Bearer ${ACCESS_TOKEN}" "${SCHEME}${MASSERVER}:${PORT}/api/admin/v1/users?page[first]=${QUERY_LIMIT}" > "$USERS_FILE"
|
||||
sessions=$(fetch_url -g -H "Authorization: Bearer ${ACCESS_TOKEN}" "${SCHEME}${MASSERVER}:${PORT}/api/admin/v1/user-sessions?filter[status]=active&page[first]=${QUERY_LIMIT}" | jq .meta[])
|
||||
|
||||
echo "multigraph mas_users_${CLEANMASSERVER}"
|
||||
if total="$(jq -r .meta[] "$USERS_FILE" | grep -E "^[0-9]+$")"; then
|
||||
if [ -n "$bot_names" ]; then
|
||||
bot_names_grep=$(echo "$bot_names" | tr ' ' '|')
|
||||
bot_names_grep="$bot_names_grep|"
|
||||
fi
|
||||
active_bots=$(jq '.data[] | select(.attributes.locked_at == null)' "$USERS_FILE" | grep -cE "\"username\": \"${bot_names_grep}.*bot\"")
|
||||
deactivated_users=$(jq '.data[] | select(.attributes.locked_at != null)' "$USERS_FILE" | grep -E "\"username\": \"" | { grep -vcE "\"${bot_names_grep}.*bot\"" || true; })
|
||||
registered_users=$(( total - active_bots ))
|
||||
active_users=$(( registered_users - deactivated_users ))
|
||||
|
||||
echo registered.value "$registered_users"
|
||||
echo active.value "$active_users"
|
||||
echo bots.value "$active_bots"
|
||||
echo deactivated.value "$deactivated_users"
|
||||
echo sessions.value "$sessions"
|
||||
else
|
||||
echo "registered.value U"
|
||||
echo "active.value U"
|
||||
echo "bots.value U"
|
||||
echo "deactivated.value U"
|
||||
echo "sessions.value U"
|
||||
fi
|
|
@ -21,6 +21,10 @@ This is a wildcard plugin. It monitors some simple values over the admin API
|
|||
of synapse matrix homeserver. Link synapse_<homeserverurl> to this file. The
|
||||
admin endpoint has to be reachable from the plugin.
|
||||
|
||||
If matrix authentication service is used, env.disable_users has to be set to
|
||||
false and the env.auth_token has to be a compatibility token from the matrix
|
||||
authentication service.
|
||||
|
||||
ln -s /usr/share/munin/plugins/synapse_ \
|
||||
/etc/munin/plugins/synapse_domain.tld
|
||||
|
||||
|
@ -28,6 +32,7 @@ Set parameters in your munin-node configuration
|
|||
|
||||
[synapse_homeserverurl]
|
||||
env.auth_token <auth_token>
|
||||
env.disable_users <default: false>
|
||||
env.interval <seconds>
|
||||
env.port <port>
|
||||
env.admin_api_path <default: /_synapse/admin>
|
||||
|
@ -48,6 +53,9 @@ To monitor a synapse instance on localhost you need following:
|
|||
It's advised to use a dedicated munin bot account (user_type bot) with admin
|
||||
rights on your matrix synapse server for this plugin.
|
||||
|
||||
If matrix authentication service is enabled on the matrix synapse server,
|
||||
disable the users check and use a compatibility token.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright (C) 2024 Sebastian L. (https://momou.ch),
|
||||
|
@ -71,6 +79,7 @@ if [ "${MUNIN_DEBUG:-0}" = 1 ]; then
|
|||
fi
|
||||
|
||||
AUTH_TOKEN="${auth_token:-}"
|
||||
DISABLE_USERS="${disable_users:-false}"
|
||||
INTERVAL="${interval:-300}"
|
||||
PORT="${port:-443}"
|
||||
ADMIN_API_PATH="${admin_api_path:-/_synapse/admin}"
|
||||
|
@ -101,8 +110,9 @@ case $1 in
|
|||
exit 0
|
||||
;;
|
||||
config)
|
||||
|
||||
cat << EOM
|
||||
USERS_CONFIG=""
|
||||
if [ "$DISABLE_USERS" != "true" ]; then
|
||||
USERS_CONFIG="
|
||||
multigraph synapse_users_${CLEANHOMESERVER}
|
||||
graph_title Synapse users on ${HOMESERVER}
|
||||
graph_args --base 1000 -l 0
|
||||
|
@ -128,7 +138,11 @@ deactivated_users.info deactivated users
|
|||
deactivated_users.min 0
|
||||
erased_users.label erased users
|
||||
erased_users.info erased users
|
||||
erased_users.min 0
|
||||
erased_users.min 0"
|
||||
fi
|
||||
|
||||
cat << EOM
|
||||
$USERS_CONFIG
|
||||
multigraph synapse_rooms_${CLEANHOMESERVER}
|
||||
graph_title Synapse spaces and rooms on ${HOMESERVER}
|
||||
graph_args --base 1000 -l 0
|
||||
|
@ -168,45 +182,48 @@ EOM
|
|||
|
||||
esac
|
||||
|
||||
mktemp_command="${mktemp_command:-/usr/bin/mktemp}"
|
||||
USERS_FILE=$($mktemp_command) || exit 73
|
||||
trap 'rm -f "$USERS_FILE"' EXIT
|
||||
|
||||
fetch_url -H "Authorization: Bearer ${AUTH_TOKEN}" "${SCHEME}${HOMESERVER}:${PORT}${ADMIN_API_PATH}/v2/users?deactivated=true&limit=${QUERY_LIMIT}" > "$USERS_FILE"
|
||||
if [ "$DISABLE_USERS" != "true" ]; then
|
||||
mktemp_command="${mktemp_command:-/usr/bin/mktemp}"
|
||||
USERS_FILE=$($mktemp_command) || exit 73
|
||||
trap 'rm -f "$USERS_FILE"' EXIT
|
||||
fetch_url -H "Authorization: Bearer ${AUTH_TOKEN}" "${SCHEME}${HOMESERVER}:${PORT}${ADMIN_API_PATH}/v2/users?deactivated=true&limit=${QUERY_LIMIT}" > "$USERS_FILE"
|
||||
fi
|
||||
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 total_number="$(jq -r .total "$USERS_FILE" | grep -E "^[0-9]+$")"; then
|
||||
puppets="$(jq -r '.users[] | select(.user_type!="bot") | select(.user_type!="support") | select(.last_seen_ts==null)' "$USERS_FILE")"
|
||||
bots="$(jq -r '.users[] | select(.user_type=="bot")' "$USERS_FILE")"
|
||||
users="$(jq -r '.users[] | select(.user_type!="support") | select(.user_type!="bot") | select(.last_seen_ts!=null)' "$USERS_FILE")"
|
||||
if [ "$DISABLE_USERS" != "true" ]; then
|
||||
echo "multigraph synapse_users_${CLEANHOMESERVER}"
|
||||
if total_number="$(jq -r .total "$USERS_FILE" | grep -E "^[0-9]+$")"; then
|
||||
puppets="$(jq -r '.users[] | select(.user_type!="bot") | select(.user_type!="support") | select(.last_seen_ts==null)' "$USERS_FILE")"
|
||||
bots="$(jq -r '.users[] | select(.user_type=="bot")' "$USERS_FILE")"
|
||||
users="$(jq -r '.users[] | select(.user_type!="support") | select(.user_type!="bot") | select(.last_seen_ts!=null)' "$USERS_FILE")"
|
||||
|
||||
puppets_number="$(echo "$puppets" | grep -c '"last_seen_ts": null')"
|
||||
bots_number="$(echo "$bots" | grep -c '"user_type": "bot"')"
|
||||
virtual_users_number=$(( puppets_number + bots_number ))
|
||||
total_registered_number=$(( total_number - virtual_users_number ))
|
||||
puppets_number="$(echo "$puppets" | grep -c '"last_seen_ts": null')"
|
||||
bots_number="$(echo "$bots" | grep -c '"user_type": "bot"')"
|
||||
virtual_users_number=$(( puppets_number + bots_number ))
|
||||
total_registered_number=$(( total_number - virtual_users_number ))
|
||||
|
||||
# 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" | jq -r 'select(.deactivated==false)' | grep -E "\"last_seen_ts\": [0-9]+")
|
||||
online_users_number="$(echo "$last_seen_times_ms" | awk -v "count=0" -F": " '$2 > "'$time_interval_ago'" {count++} END {print count}')"
|
||||
|
||||
echo total_registered.value "$total_registered_number"
|
||||
echo active_users.value "$(echo "$users" | grep -c '"deactivated": false')"
|
||||
echo bots.value "$(echo "$bots" | grep -c '"deactivated": false')"
|
||||
echo online_users.value "$online_users_number"
|
||||
echo deactivated_users.value "$(echo "$users" | grep -c '"deactivated": true')"
|
||||
echo erased_users.value "$(echo "$users" | grep -c '"erased": true')"
|
||||
else
|
||||
echo "total_registered.value U"
|
||||
echo "active_users.value U"
|
||||
echo "bots.value U"
|
||||
echo "online_users.value U"
|
||||
echo "deactivated_users.value U"
|
||||
echo "erased_users.value U"
|
||||
# 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" | jq -r 'select(.deactivated==false)' | grep -E "\"last_seen_ts\": [0-9]+")
|
||||
online_users_number="$(echo "$last_seen_times_ms" | awk -v "count=0" -F": " '$2 > "'$time_interval_ago'" {count++} END {print count}')"
|
||||
|
||||
echo total_registered.value "$total_registered_number"
|
||||
echo active_users.value "$(echo "$users" | grep -c '"deactivated": false')"
|
||||
echo bots.value "$(echo "$bots" | grep -c '"deactivated": false')"
|
||||
echo online_users.value "$online_users_number"
|
||||
echo deactivated_users.value "$(echo "$users" | grep -c '"deactivated": true')"
|
||||
echo erased_users.value "$(echo "$users" | grep -c '"erased": true')"
|
||||
else
|
||||
echo "total_registered.value U"
|
||||
echo "active_users.value U"
|
||||
echo "bots.value U"
|
||||
echo "online_users.value U"
|
||||
echo "deactivated_users.value U"
|
||||
echo "erased_users.value U"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo multigraph synapse_rooms_"${CLEANHOMESERVER}"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue