#!/bin/sh # shellcheck shell=dash set -e : << =cut =head1 NAME nextcloud_ - Monitor usage of nextcloud instances =head1 APPLICABLE SYSTEMS Nexcloud instances =head1 CONFIGURATION Requires installed curl and jq, a command-line json processor. This is a wildcard plugin. To monitor a nextcloud instance, link nextcloud_ to this file. You can even append a port (:8443) to the file if needed. For example, ln -s /usr/share/munin/plugins/nextcloud_ \ /etc/munin/plugins/nextcloud_cloud.domain.tld Set username and password in your munin-node configuration [nextcloud_cloud.domain.tld] env.username # XXX: use serverinfo_token instead env.password # XXX: ditto env.serverinfo_token env.api_path env.scheme env.timeout env.updates_warning env.check_app_updates It's advised to use a serverinfo token, or at least to set an app password (for this plugin) in your nextcloud instance and not to use the "real" password of your nextcloud user. You can generate a token with, e.g., TOKEN=$(openssl rand -hex 32) and then set it with ./occ config:app:set serverinfo token --value ${TOKEN} =head1 AUTHOR Copyright (C) 2020 Sebastian L. (https://momou.ch), 2020,2025 Olivier Mehani =head1 LICENSE SPDX-License-Identifier: GPL-2.0 =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 CHECK_APP_UPDATES="${check_app_updates:-true}" APP_UPDATES_CONFIG="" APP_UPDATES_VALUE="" API_PATH="${api_path:-/ocs/v2.php/apps/serverinfo/api/v1/info}?format=json&skipApps=$check_app_updates" DOMAIN="${0##*nextcloud_}" SCHEME="${scheme:-https}://" TIMEOUT="${timeout:-2}" CLEANDOMAIN="$(clean_fieldname "${DOMAIN}")" if [ "$CHECK_APP_UPDATES" != "false" ]; then UPDATES_WARNING="${updates_warning:-1}" APP_UPDATES_CONFIG="num_updates_available.label available app updates num_updates_available.info number of available app updates num_updates_available.min 0 num_updates_available.warning ${UPDATES_WARNING}" APP_UPDATES_VALUE="num_updates_available.value \(.nextcloud.system.apps.num_updates_available)" fi SERVERINFO_TOKEN="${serverinfo_token:-}" if [ -z "${SERVERINFO_TOKEN}" ]; then USERNAME="${username:-}" PASSWORD="${password:-}" fi fetch_url () { curl -s -f -m "${TIMEOUT}" \ ${SERVERINFO_TOKEN:+-H "NC-Token: ${SERVERINFO_TOKEN}"} \ ${USERNAME:+-u "${USERNAME}:${PASSWORD}"} \ "$@" } 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 "${SCHEME}${DOMAIN}${API_PATH}" \ | grep -iq "Content-Type: application/json" \ && echo "yes" \ || echo "no (invalid or empty response from nextcloud serverinfo api)" fi exit 0 ;; config) cat << EOM multigraph nextcloud_users_${CLEANDOMAIN} graph_title Nextcloud users on ${DOMAIN} graph_args --base 1000 -l 0 graph_printf %.0lf graph_vlabel connected users graph_info number of connected user graph_category cloud last5minutes.label last 5 minutes last5minutes.info users connected in the last 5 minutes last5minutes.min 0 last1hour.label last hour last1hour.info users connected in the last hour last1hour.min 0 last24hours.label last 24 hours last24hours.info users connected in the last 24 hours last24hours.min 0 num_users.label number of users num_users.info total number of users num_users.min 0 multigraph nextcloud_files_${CLEANDOMAIN} graph_title Nextcloud files on ${DOMAIN} graph_args --base 1000 -l 0 graph_printf %.0lf graph_vlabel number of files graph_info number of files graph_category cloud num_files.label number of files num_files.info current number of files num_files.min 0 multigraph nextcloud_shares_${CLEANDOMAIN} graph_title Nextcloud shares on ${DOMAIN} graph_args --base 1000 -l 0 graph_printf %.0lf graph_vlabel number of shares graph_info number of shares graph_category cloud num_shares.label total number of shares num_shares.info current over all total of shares num_shares.min 0 num_shares_user.label user shares num_shares_user.info current total of user shares num_shares_user.min 0 num_shares_groups.label group shares num_shares_groups.info current total of group shares num_shares_groups.min 0 num_shares_link.label link shares num_shares_link.info current total of link shares num_shares_link.min 0 num_shares_mail.label mail shares num_shares_mail.info current total of mail shares num_shares_mail.min 0 num_shares_room.label room shares num_shares_room.info current total of room shares num_shares_room.min 0 num_shares_link_no_password.label link shares without password protection num_shares_link_no_password.info current total of link shares without password protection num_shares_link_no_password.min 0 num_fed_shares_sent.label federated shares sent num_fed_shares_sent.info current total of federated shares sent num_fed_shares_sent.min 0 num_fed_shares_received.label federated shares received num_fed_shares_received.info current total of federated shares received num_fed_shares_received.min 0 multigraph nextcloud_dbsize_${CLEANDOMAIN} graph_title Nextcloud database size on ${DOMAIN} graph_args --base 1024 -l 0 graph_vlabel size in bytes graph_info database database size in bytes graph_category cloud db_size.label database size in bytes db_size.info database size in bytes db_size.draw AREA db_size.min 0 multigraph nextcloud_storages_${CLEANDOMAIN} graph_title Nextcloud storages on ${DOMAIN} graph_args --base 1000 -l 0 graph_printf %.0lf graph_vlabel number graph_info number of storages graph_category cloud num_storages.label total number of storages num_storages.info current total of storages num_storages.min 0 num_storages_local.label number of local storages num_storages_local.info current number of local storages num_storages_local.min 0 num_storages_home.label number of home storages num_storages_home.info current number of home storages num_storages_home.min 0 num_storages_other.label number of other storages num_storages_other.info current number of other storages num_storages_other.min 0 multigraph nextcloud_apps_${CLEANDOMAIN} graph_title Nextcloud apps on ${DOMAIN} graph_args --base 1000 -l 0 graph_printf %.0lf graph_vlabel apps graph_info number of installed and updatable apps graph_category cloud $APP_UPDATES_CONFIG num_installed.label installed apps num_installed.info number of installed apps num_installed.min 0 EOM exit 0 ;; esac fetch_url "${SCHEME}${DOMAIN}${API_PATH}" \ | sed 's/\\/\\\\/g' \ | jq -r '.ocs.data | @text " multigraph nextcloud_users_'"${CLEANDOMAIN}"' last5minutes.value \(.activeUsers.last5minutes) last1hour.value \(.activeUsers.last1hour) last24hours.value \(.activeUsers.last24hours) num_users.value \(.nextcloud.storage.num_users) multigraph nextcloud_files_'"${CLEANDOMAIN}"' num_files.value \(.nextcloud.storage.num_files) multigraph nextcloud_storages_'"${CLEANDOMAIN}"' num_storages.value \(.nextcloud.storage.num_storages) num_storages_local.value \(.nextcloud.storage.num_storages_local) num_storages_home.value \(.nextcloud.storage.num_storages_home) num_storages_other.value \(.nextcloud.storage.num_storages_other) multigraph nextcloud_shares_'"${CLEANDOMAIN}"' num_shares.value \(.nextcloud.shares.num_shares) num_shares_user.value \(.nextcloud.shares.num_shares_user) num_shares_groups.value \(.nextcloud.shares.num_shares_groups) num_shares_link.value \(.nextcloud.shares.num_shares_link) num_shares_mail.value \(.nextcloud.shares.num_shares_mail) num_shares_room.value \(.nextcloud.shares.num_shares_room) num_shares_link_no_password.value \(.nextcloud.shares.num_shares_link_no_password) num_fed_shares_sent.value \(.nextcloud.shares.num_fed_shares_sent) num_fed_shares_received.value \(.nextcloud.shares.num_fed_shares_received) multigraph nextcloud_dbsize_'"${CLEANDOMAIN}"' db_size.value \(.server.database.size) multigraph nextcloud_apps_'"${CLEANDOMAIN}"' num_installed.value \(.nextcloud.system.apps.num_installed) '"$APP_UPDATES_VALUE"' "' \ | sed 's/ null$/ U/'