mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
ILIAS plugin v2: Use bash+CLI and combine graphs
Combine multiple graphs into one as suggested by @sumpfralle.
This commit is contained in:
parent
167c204db2
commit
890e971c2c
BIN
plugins/ilias/example-graphs/ilias-day.png
Normal file
BIN
plugins/ilias/example-graphs/ilias-day.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
Before Width: | Height: | Size: 19 KiB |
@ -1,254 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
: << =cut
|
|
||||||
|
|
||||||
=head1 NAME
|
|
||||||
|
|
||||||
ilias - Munin plugin to monitor L<ILIAS|https://ilias.de/> 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 <per-pascal.grube@tik.uni-stuttgart.de>
|
|
||||||
|
|
||||||
Copyright 2018 L<Felix Pahlow|https://wohlpa.de/>
|
|
||||||
(L<email|mailto:felix.pahlow@itz.uni-halle.de>)
|
|
||||||
|
|
||||||
=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<GitHub
|
|
||||||
|https://github.com/munin-monitoring/contrib/tree/master/plugins/ilias>
|
|
||||||
|
|
||||||
=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()
|
|
||||||
|
|
236
plugins/ilias/ilias_session
Executable file
236
plugins/ilias/ilias_session
Executable file
@ -0,0 +1,236 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Munin plugin for ILIAS
|
||||||
|
|
||||||
|
: << =cut
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
ilias_session - Munin plugin to monitor L<ILIAS|https://ilias.de/> 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<Felix Pahlow|https://wohlpa.de/>
|
||||||
|
(L<email|mailto:felix.pahlow@wohlpa.de>)
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
Licensed under the MIT license:
|
||||||
|
https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
=head1 CONTRIBUTE
|
||||||
|
|
||||||
|
Find this plugin on L<GitHub
|
||||||
|
|https://github.com/munin-monitoring/contrib/tree/master/plugins/ilias>
|
||||||
|
|
||||||
|
=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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user