#!/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()