diff --git a/plugins/ilias/example-graphs/ilias-day.png b/plugins/ilias/example-graphs/ilias-day.png new file mode 100644 index 00000000..130604cf Binary files /dev/null and b/plugins/ilias/example-graphs/ilias-day.png differ diff --git a/plugins/ilias/example-graphs/ilias_sessions-day.png b/plugins/ilias/example-graphs/ilias_sessions-day.png deleted file mode 100644 index f53b11df..00000000 Binary files a/plugins/ilias/example-graphs/ilias_sessions-day.png and /dev/null differ diff --git a/plugins/ilias/ilias_ b/plugins/ilias/ilias_ deleted file mode 100755 index 39bf1367..00000000 --- a/plugins/ilias/ilias_ +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -""" -: << =cut - -=head1 NAME - -ilias - Munin plugin to monitor L open source -learning management system - -=head1 DESCRIPTION - -Reads session and user statistcs from any ILIAS MySQLdb database. - -https://ilias.de/ | http://gallery.munin-monitoring.org/contrib/cms-index.html - -This plugin requires python3 and python3-mysqldb. - -There is a check for the the filename suffix _ (from the symlink) in place -to decide which value to output. Symlink the file for each value you want -displayed -example: - ln -s /usr/local/munin_plugins/ilias_ /etc/munin/plugins/ilias_sessions - -In order to get precise results, please ensure your MySQL server has the same -time as your ILIAS application server. Timezone does not matter. - -=head1 CONFIGURATION - -The plugin needs the following configuration settings e.g. in -/etc/munin/plugin-conf.d/ilias.conf - - [ilias_*] - env.ildbuser ilias - env.ildbpassword youriliaspasword - env.ildb ilias - env.ildbhost localhost - env.ildbport 3306 - - -=head1 AUTHOR - -Copyright 2016 Pascal Seeland - -Copyright 2018 L - (L) - -=head1 LICENSE - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished to do so, -provided that the above copyright notice(s) and this permission notice -appear in all copies of the Software and that both the above copyright -notice(s) and this permission notice appear in supporting documentation. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE -LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER -IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall not -be used in advertising or otherwise to promote the sale, use or other -dealings in this Software without prior written authorization of the -copyright holder. - -=head1 CONTRIBUTE - -Find this plugin on L - -=head1 MAGIC MARKERS - - #%# family=auto - #%# capabilities=autoconf suggest - -=head1 VERSION - - 1.0 - -=head1 CHANGELOG - -=head2 1.0 - 2018/03/19 - - first release - -=cut -""" - -import os -import sys -import pkgutil - - -class ILIAS(): - pluginname = sys.argv[0].split('_')[1] - - def __init__(self): - self.con = None - self.user = os.environ.get('ildbuser', 'root') - self.pw = os.environ.get('ildbpassword', '') - self.ildb = os.environ.get('ildb', 'ilias') - self.ildbhost = os.environ.get('ildbhost', 'localhost') - self.ildbport = int(os.environ.get('ildbport', 3306)) - - def db_modules_available(self): - return pkgutil.find_loader("MySQLdb") - - def get_connection(self): - import MySQLdb - return MySQLdb.connect(host=self.ildbhost, - port=self.ildbport, - user=self.user, - passwd=self.pw, - db=self.ildb) - - def connectdb(self): - self.con = self.get_connection() - - def config_sessions(self): - print("graph_title ILIAS Session") - print("graph_info Number of active ILIAS user sessions") - print("graph_vlabel ilsessions") - print("graph_category cms") - print("ilsessions.label ilSessions") - print("ilsessions.min 0") - print("ilsessions.draw AREA") - - def execute_sessions(self): - cursor = self.con.cursor() - cursor.execute( - "SELECT COUNT( user_id ) " - "FROM usr_session " - "WHERE `expires` > UNIX_TIMESTAMP( NOW( ) ) AND user_id != 0" - ) - usrs = cursor.fetchone()[0] - print("ilsessions.value %s" % (usrs)) - - def config_5minavg(self): - print("graph_title ILIAS 5 avg") - print("graph_info ILIAS sessions created or " - "updated during the last 5 minutes") - print("graph_vlabel il5minavg") - print("graph_category cms") - print("il5minavg.label 5 min Count") - print("il5minavg.min 0") - print("il5minavg.draw AREA") - - def execute_5minavg(self): - cursor = self.con.cursor() - cursor.execute( - "SELECT COUNT( user_id ) " - "FROM usr_session " - "WHERE 5 * 60 > UNIX_TIMESTAMP( NOW( ) ) - ctime AND user_id != 0" - ) - usrs = cursor.fetchone()[0] - print("il5minavg.value %s" % (usrs)) - - def config_60minavg(self): - print("graph_title ILIAS 60 avg") - print("graph_info ILIAS sessions created or " - "updated during the last 60 minutes") - print("graph_vlabel il60minavg") - print("graph_category cms") - print("il60minavg.label 60 min Count") - print("il60minavg.min 0") - print("il60minavg.draw AREA") - - def execute_60minavg(self): - cursor = self.con.cursor() - cursor.execute( - "SELECT COUNT( user_id ) " - "FROM usr_session " - "WHERE 60 * 60 > UNIX_TIMESTAMP( NOW( ) ) - ctime AND user_id != 0" - ) - usrs = cursor.fetchone()[0] - print("il60minavg.value %s" % (usrs)) - - def config_total1day(self): - print("graph_title Users in 24h") - print("graph_info ILIAS users logging in during last 24h") - print("graph_vlabel iltotal1day") - print("graph_category cms") - print("iltotal1day.label User/24h") - print("iltotal1day.min 0") - print("iltotal1day.draw AREA") - - def execute_total1day(self): - cursor = self.con.cursor() - cursor.execute( - "SELECT COUNT( usr_id ) " - "FROM `usr_data` " - "WHERE last_login >= DATE_SUB( NOW( ) , INTERVAL 1 DAY )") - usrs = cursor.fetchone()[0] - print("iltotal1day.value %s" % (usrs)) - - def run(self): - cmd = ((len(sys.argv) > 1) and sys.argv[1]) or "execute" - function = None - - if cmd == "config": - function = "config" - elif cmd == "suggest": - print("sessions") - print("5minavg") - print("60minavg") - print("total1day") - elif cmd == "autoconf": - if not self.db_modules_available(): - print("no (Please install the MySQLdb python3 module)") - else: - try: - con = self.get_connection() - cursor = con.cursor() - cursor.execute("SELECT COUNT( component ) " - "FROM il_pluginslot") - con.close() - except _mysql.Error as e: - print("no (Error %d: %s - Database configuration missing?)" - % (e.args[0], e.args[1])) - else: - print("yes") - else: - function = "execute" - - if function is not None: - if not self.db_modules_available(): - print("U (Please install the MySQLdb python3 module)") - else: - self.connectdb() - try: - func = getattr(self, "%s_%s" % (function, self.pluginname)) - except AttributeError: - print('function not found "%s" (%s)' % - ("config_%s" % self.pluginname, "self")) - else: - func() - - if self.con: - self.con.close() - - sys.exit(0) - - -if __name__ == "__main__": - ILIAS().run() - diff --git a/plugins/ilias/ilias_session b/plugins/ilias/ilias_session new file mode 100755 index 00000000..5f85a7c4 --- /dev/null +++ b/plugins/ilias/ilias_session @@ -0,0 +1,236 @@ +#!/usr/bin/env bash +# Munin plugin for ILIAS + +: << =cut + +=head1 NAME + +ilias_session - Munin plugin to monitor L open source +learning management system's sessions + +=head1 DESCRIPTION + +Reads session and user statistcs from any ILIAS MySQL/MariaDB database. + +https://ilias.de/ | http://gallery.munin-monitoring.org/contrib/cms-index.html + +Requirements: + +bash version 4 is required for associative array support. +This plugin requires mysql CLI or a compatible client being available. + +In order to get precise results, please ensure your MySQL server has the same +time as your ILIAS application server. Timezone does not matter. + +=head1 CONFIGURATION + +The plugin needs the following configuration settings e.g. in +/etc/munin/plugin-conf.d/ilias.conf + + [ilias_session] + env.ildbuser ilias + env.ildbpassword youriliaspasword + env.ildb ilias + env.ildbhost localhost + env.ildbport 3306 + +WARNING: Setting env.ildbpassword will possibly expose the database password +to other processes and might be insecure. + +=head1 AUTHOR + +Copyright 2018 L + (L) + +=head1 LICENSE + +Licensed under the MIT license: +https://opensource.org/licenses/MIT + +=head1 CONTRIBUTE + +Find this plugin on L + +=head1 MAGIC MARKERS + + #%# family=auto + #%# capabilities=autoconf + +=head1 VERSION + + 2.0 + +=head1 CHANGELOG + +=head2 2.0 - 2018/04/20 + + first sh release + +=head2 1.0 - 2018/03/19 + + first release + +=cut + +# Include plugin.sh +# shellcheck source=/dev/null +. "${MUNIN_LIBDIR:-}/plugins/plugin.sh" + +# Shell options +set -o nounset # Like perl use strict; + +# Graph settings +global_attr=" + graph_title ILIAS session and logins + graph_category cms + graph_args --lower-limit 0 + graph_vlabel occurences + graph_info Number of active ILIAS user sessions and logins +" + +declare -A d_attr=( \ + [0,field]=iltotal1day \ + [0,type]=GAUGE \ + [0,draw]=LINE \ + [0,label]='users logged in within day' \ + [0,sql]="SELECT COUNT( usr_id ) AS C + FROM \`usr_data\` + WHERE last_login >= DATE_SUB( NOW( ) , INTERVAL 1 DAY ) + " \ + [1,field]=ilsessions \ + [1,type]=GAUGE \ + [1,draw]=LINE \ + [1,label]='active sessions' \ + [1,sql]="SELECT COUNT( user_id ) AS C + FROM usr_session + WHERE \`expires\` > UNIX_TIMESTAMP( NOW( ) ) AND user_id != 0 + " \ + [2,field]=il60minavg \ + [2,type]=GAUGE \ + [2,draw]=LINE \ + [2,label]='sessions created/updated within 1h' \ + [2,sql]="SELECT COUNT( user_id ) AS C + FROM usr_session + WHERE 60 * 60 > UNIX_TIMESTAMP( NOW( ) ) - ctime AND user_id != 0 + " \ + [3,field]=il5minavg \ + [3,type]=GAUGE \ + [3,draw]=LINE \ + [3,label]='sessions created/updated within 5min' \ + [3,sql]="SELECT COUNT( user_id ) AS C + FROM usr_session + WHERE 5 * 60 > UNIX_TIMESTAMP( NOW( ) ) - ctime AND user_id != 0 + " \ +) + +# Read the environment and apply defaults +DB_CLI_TOOL="${ildbcli:-mysql}" +DB_CLI_CMD="$(command -v "${DB_CLI_TOOL}")" +DB_HOST="${ildbhost:-localhost}" +DB_PORT="${ildbport:-3306}" +DB="${ildb:-ilias}" +DB_USER="${ildbuser:-root}" +DB_PASSWORD="${ildbpassword:-}" + +# Functions + +autoconf() { + if command -v "${DB_CLI_TOOL}" >/dev/null ; then + echo yes + else + echo "no (failed to find executable '${DB_CLI_TOOL}')" + fi +} + +config() { + local label_max_length=45 + local i=0 + + # print global attributes + echo "$global_attr" | sed -e 's/^ *//' -e '/^$/d' + + i=0 + # -v varname + # True if the shell variable varname is set (has been assigned a value). + # https://stackoverflow.com/a/45385463/2683737 + while [[ -v d_attr[$i,field] ]]; do + field=${d_attr[$i,field]} + echo "$field.type ${d_attr[$i,type]}" + echo "$field.draw ${d_attr[$i,draw]}" + echo "$field.label ${d_attr[$i,label]:0:${label_max_length}}" + echo "$field.min 0" + ((++i)) + done +} + +# Join a bash array $1 is the glue +join_by() { + local d=$1 + shift + echo -n "$1" + shift + printf "%s" "${@/#/$d}" +} + +fetch() { + local i=0 + local query=() + local query_string="" + declare -a results + + # create an array of queries + i=0 + while [[ -v d_attr[$i,field] ]]; do + query+=("${d_attr[$i,sql]}") + ((++i)) + done + + # build query by joining the array elements + query_string=$(join_by " UNION ALL " "${query[@]}") + + # obtain result using CLI call; don't supply password through + # command line; note that MySQL considers it insecure using + # an environment variable: + # >This method of specifying your MySQL password must + # >be considered extremely insecure and should not be used. + # >Some versions of ps include an option to display the + # >environment of running processes. [...] + result=$(MYSQL_PWD="$DB_PASSWORD" \ + "$DB_CLI_CMD" \ + --skip-column-names \ + -h "$DB_HOST" \ + -u "$DB_USER" \ + -P "$DB_PORT" \ + "$DB" \ + -e "$query_string" ) + + # initialize array + mapfile -t results <<< "$result" + + # extract result and echo it to stdout, which is + # captured by Munin + i=0 + while [[ -v d_attr[$i,field] ]]; do + echo "${d_attr[$i,field]}.value ${results[$i]}" + ((++i)) + done +} + + +# Main +case ${1:-} in +autoconf) + autoconf + ;; +config) + config + [ "${MUNIN_CAP_DIRTYCONFIG:-}" = "1" ] && fetch + ;; +*) + fetch + ;; +esac + +exit 0 +