Projet

Général

Profil

Révision 890e971c

ID890e971c2ca0814ad569ac5d5eb98f17db4df8db
Parent 167c204d
Enfant bd174786

Ajouté par Felix Pahlow (private) il y a plus de 7 ans

ILIAS plugin v2: Use bash+CLI and combine graphs

Combine multiple graphs into one as suggested by
@sumpfralle.

Voir les différences:

plugins/ilias/ilias_
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3

  
4
"""
5
: << =cut
6

  
7
=head1 NAME
8

  
9
ilias - Munin plugin to monitor L<ILIAS|https://ilias.de/> open source
10
learning management system
11

  
12
=head1 DESCRIPTION
13

  
14
Reads session and user statistcs from any ILIAS MySQLdb database.
15

  
16
https://ilias.de/ | http://gallery.munin-monitoring.org/contrib/cms-index.html
17

  
18
This plugin requires python3 and python3-mysqldb.
19

  
20
There is a check for the the filename suffix  _ (from the symlink) in place
21
to decide which value to output. Symlink the file for each value you want
22
displayed
23
example:
24
    ln -s /usr/local/munin_plugins/ilias_ /etc/munin/plugins/ilias_sessions
25

  
26
In order to get precise results, please ensure your MySQL server has the same
27
time as your ILIAS application server. Timezone does not matter.
28

  
29
=head1 CONFIGURATION
30

  
31
The plugin needs the following configuration settings e.g. in
32
/etc/munin/plugin-conf.d/ilias.conf
33

  
34
    [ilias_*]
35
        env.ildbuser ilias
36
        env.ildbpassword youriliaspasword
37
        env.ildb ilias
38
        env.ildbhost localhost
39
        env.ildbport 3306
40

  
41

  
42
=head1 AUTHOR
43

  
44
Copyright 2016 Pascal Seeland <per-pascal.grube@tik.uni-stuttgart.de>
45

  
46
Copyright 2018 L<Felix Pahlow|https://wohlpa.de/>
47
               (L<email|mailto:felix.pahlow@itz.uni-halle.de>)
48

  
49
=head1 LICENSE
50

  
51
Permission is hereby granted, free of charge, to any person obtaining a copy
52
of this software and associated documentation files (the "Software"), to deal
53
in the Software without restriction, including without limitation the rights
54
to use, copy, modify, merge, publish, distribute, and/or sell copies of the
55
Software, and to permit persons to whom the Software is furnished to do so,
56
provided that the above copyright notice(s) and this permission notice
57
appear in all copies of the Software and that both the above copyright
58
notice(s) and this permission notice appear in supporting documentation.
59

  
60
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
61
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
62
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
63
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
64
LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR
65
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
66
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
67
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
68

  
69
Except as contained in this notice, the name of a copyright holder shall not
70
be used in advertising or otherwise to promote the sale, use or other
71
dealings in this Software without prior written authorization of the
72
copyright holder.
73

  
74
=head1 CONTRIBUTE
75

  
76
Find this plugin on L<GitHub
77
|https://github.com/munin-monitoring/contrib/tree/master/plugins/ilias>
78

  
79
=head1 MAGIC MARKERS
80

  
81
 #%# family=auto
82
 #%# capabilities=autoconf suggest
83

  
84
=head1 VERSION
85

  
86
    1.0
87

  
88
=head1 CHANGELOG
89

  
90
=head2 1.0 - 2018/03/19
91

  
92
    first release
93

  
94
=cut
95
"""
96

  
97
import os
98
import sys
99
import pkgutil
100

  
101

  
102
class ILIAS():
103
    pluginname = sys.argv[0].split('_')[1]
104

  
105
    def __init__(self):
106
        self.con = None
107
        self.user = os.environ.get('ildbuser', 'root')
108
        self.pw = os.environ.get('ildbpassword', '')
109
        self.ildb = os.environ.get('ildb', 'ilias')
110
        self.ildbhost = os.environ.get('ildbhost', 'localhost')
111
        self.ildbport = int(os.environ.get('ildbport', 3306))
112

  
113
    def db_modules_available(self):
114
        return pkgutil.find_loader("MySQLdb")
115

  
116
    def get_connection(self):
117
        import MySQLdb
118
        return MySQLdb.connect(host=self.ildbhost,
119
                               port=self.ildbport,
120
                               user=self.user,
121
                               passwd=self.pw,
122
                               db=self.ildb)
123

  
124
    def connectdb(self):
125
        self.con = self.get_connection()
126

  
127
    def config_sessions(self):
128
        print("graph_title ILIAS Session")
129
        print("graph_info Number of active ILIAS user sessions")
130
        print("graph_vlabel ilsessions")
131
        print("graph_category cms")
132
        print("ilsessions.label ilSessions")
133
        print("ilsessions.min 0")
134
        print("ilsessions.draw AREA")
135

  
136
    def execute_sessions(self):
137
        cursor = self.con.cursor()
138
        cursor.execute(
139
            "SELECT COUNT( user_id ) "
140
            "FROM usr_session "
141
            "WHERE `expires` > UNIX_TIMESTAMP( NOW( ) ) AND user_id != 0"
142
        )
143
        usrs = cursor.fetchone()[0]
144
        print("ilsessions.value %s" % (usrs))
145

  
146
    def config_5minavg(self):
147
        print("graph_title ILIAS 5 avg")
148
        print("graph_info ILIAS sessions created or "
149
              "updated during the last 5 minutes")
150
        print("graph_vlabel il5minavg")
151
        print("graph_category cms")
152
        print("il5minavg.label 5 min Count")
153
        print("il5minavg.min 0")
154
        print("il5minavg.draw AREA")
155

  
156
    def execute_5minavg(self):
157
        cursor = self.con.cursor()
158
        cursor.execute(
159
            "SELECT COUNT( user_id ) "
160
            "FROM usr_session "
161
            "WHERE 5 * 60 > UNIX_TIMESTAMP( NOW( ) ) - ctime AND user_id != 0"
162
        )
163
        usrs = cursor.fetchone()[0]
164
        print("il5minavg.value %s" % (usrs))
165

  
166
    def config_60minavg(self):
167
        print("graph_title ILIAS 60 avg")
168
        print("graph_info ILIAS sessions created or "
169
              "updated during the last 60 minutes")
170
        print("graph_vlabel il60minavg")
171
        print("graph_category cms")
172
        print("il60minavg.label 60 min Count")
173
        print("il60minavg.min 0")
174
        print("il60minavg.draw AREA")
175

  
176
    def execute_60minavg(self):
177
        cursor = self.con.cursor()
178
        cursor.execute(
179
            "SELECT COUNT( user_id ) "
180
            "FROM usr_session "
181
            "WHERE 60 * 60 > UNIX_TIMESTAMP( NOW( ) ) - ctime AND user_id != 0"
182
        )
183
        usrs = cursor.fetchone()[0]
184
        print("il60minavg.value %s" % (usrs))
185

  
186
    def config_total1day(self):
187
        print("graph_title Users in 24h")
188
        print("graph_info ILIAS users logging in during last 24h")
189
        print("graph_vlabel iltotal1day")
190
        print("graph_category cms")
191
        print("iltotal1day.label User/24h")
192
        print("iltotal1day.min 0")
193
        print("iltotal1day.draw AREA")
194

  
195
    def execute_total1day(self):
196
        cursor = self.con.cursor()
197
        cursor.execute(
198
            "SELECT COUNT( usr_id ) "
199
            "FROM `usr_data` "
200
            "WHERE last_login >= DATE_SUB( NOW( ) , INTERVAL 1 DAY )")
201
        usrs = cursor.fetchone()[0]
202
        print("iltotal1day.value %s" % (usrs))
203

  
204
    def run(self):
205
        cmd = ((len(sys.argv) > 1) and sys.argv[1]) or "execute"
206
        function = None
207

  
208
        if cmd == "config":
209
            function = "config"
210
        elif cmd == "suggest":
211
            print("sessions")
212
            print("5minavg")
213
            print("60minavg")
214
            print("total1day")
215
        elif cmd == "autoconf":
216
            if not self.db_modules_available():
217
                print("no (Please install the MySQLdb python3 module)")
218
            else:
219
                try:
220
                    con = self.get_connection()
221
                    cursor = con.cursor()
222
                    cursor.execute("SELECT COUNT( component ) "
223
                                   "FROM il_pluginslot")
224
                    con.close()
225
                except _mysql.Error as e:
226
                    print("no (Error %d: %s - Database configuration missing?)"
227
                          % (e.args[0], e.args[1]))
228
                else:
229
                    print("yes")
230
        else:
231
            function = "execute"
232

  
233
        if function is not None:
234
            if not self.db_modules_available():
235
                print("U (Please install the MySQLdb python3 module)")
236
            else:
237
                self.connectdb()
238
                try:
239
                    func = getattr(self, "%s_%s" % (function, self.pluginname))
240
                except AttributeError:
241
                    print('function not found "%s" (%s)' %
242
                          ("config_%s" % self.pluginname, "self"))
243
                else:
244
                    func()
245

  
246
        if self.con:
247
            self.con.close()
248

  
249
        sys.exit(0)
250

  
251

  
252
if __name__ == "__main__":
253
    ILIAS().run()
254

  
plugins/ilias/ilias_session
1
#!/usr/bin/env bash
2
# Munin plugin for ILIAS
3

  
4
: << =cut
5

  
6
=head1 NAME
7

  
8
ilias_session - Munin plugin to monitor L<ILIAS|https://ilias.de/> open source
9
learning management system's sessions
10

  
11
=head1 DESCRIPTION
12

  
13
Reads session and user statistcs from any ILIAS MySQL/MariaDB database.
14

  
15
https://ilias.de/ | http://gallery.munin-monitoring.org/contrib/cms-index.html
16

  
17
Requirements:
18

  
19
bash version 4 is required for associative array support.
20
This plugin requires mysql CLI or a compatible client being available.
21

  
22
In order to get precise results, please ensure your MySQL server has the same
23
time as your ILIAS application server. Timezone does not matter.
24

  
25
=head1 CONFIGURATION
26

  
27
The plugin needs the following configuration settings e.g. in
28
/etc/munin/plugin-conf.d/ilias.conf
29

  
30
    [ilias_session]
31
        env.ildbuser ilias
32
        env.ildbpassword youriliaspasword
33
        env.ildb ilias
34
        env.ildbhost localhost
35
        env.ildbport 3306
36

  
37
WARNING: Setting env.ildbpassword will possibly expose the database password
38
to other processes and might be insecure.
39

  
40
=head1 AUTHOR
41

  
42
Copyright 2018 L<Felix Pahlow|https://wohlpa.de/>
43
               (L<email|mailto:felix.pahlow@wohlpa.de>)
44

  
45
=head1 LICENSE
46

  
47
Licensed under the MIT license:
48
https://opensource.org/licenses/MIT
49

  
50
=head1 CONTRIBUTE
51

  
52
Find this plugin on L<GitHub
53
|https://github.com/munin-monitoring/contrib/tree/master/plugins/ilias>
54

  
55
=head1 MAGIC MARKERS
56

  
57
 #%# family=auto
58
 #%# capabilities=autoconf
59

  
60
=head1 VERSION
61

  
62
    2.0
63

  
64
=head1 CHANGELOG
65

  
66
=head2 2.0 - 2018/04/20
67

  
68
    first sh release
69

  
70
=head2 1.0 - 2018/03/19
71

  
72
    first release
73

  
74
=cut
75

  
76
# Include plugin.sh
77
# shellcheck source=/dev/null
78
. "${MUNIN_LIBDIR:-}/plugins/plugin.sh"
79

  
80
# Shell options
81
set -o nounset  # Like perl use strict;
82

  
83
# Graph settings
84
global_attr="
85
    graph_title ILIAS session and logins
86
    graph_category cms
87
    graph_args --lower-limit 0
88
    graph_vlabel occurences
89
    graph_info Number of active ILIAS user sessions and logins
90
"
91

  
92
declare -A d_attr=( \
93
    [0,field]=iltotal1day \
94
    [0,type]=GAUGE \
95
    [0,draw]=LINE \
96
    [0,label]='users logged in within day' \
97
    [0,sql]="SELECT COUNT( usr_id ) AS C
98
           FROM \`usr_data\`
99
           WHERE last_login >= DATE_SUB( NOW( ) , INTERVAL 1 DAY )
100
    " \
101
    [1,field]=ilsessions \
102
    [1,type]=GAUGE \
103
    [1,draw]=LINE \
104
    [1,label]='active sessions' \
105
    [1,sql]="SELECT COUNT( user_id ) AS C
106
           FROM usr_session
107
           WHERE \`expires\` > UNIX_TIMESTAMP( NOW( ) ) AND user_id != 0
108
    " \
109
    [2,field]=il60minavg \
110
    [2,type]=GAUGE \
111
    [2,draw]=LINE \
112
    [2,label]='sessions created/updated within 1h' \
113
    [2,sql]="SELECT COUNT( user_id ) AS C
114
           FROM usr_session
115
           WHERE 60 * 60 > UNIX_TIMESTAMP( NOW( ) ) - ctime AND user_id != 0
116
    " \
117
    [3,field]=il5minavg \
118
    [3,type]=GAUGE \
119
    [3,draw]=LINE \
120
    [3,label]='sessions created/updated within 5min' \
121
    [3,sql]="SELECT COUNT( user_id ) AS C
122
           FROM usr_session
123
           WHERE 5 * 60 > UNIX_TIMESTAMP( NOW( ) ) - ctime AND user_id != 0
124
    " \
125
)
126

  
127
# Read the environment and apply defaults
128
DB_CLI_TOOL="${ildbcli:-mysql}"
129
DB_CLI_CMD="$(command -v "${DB_CLI_TOOL}")"
130
DB_HOST="${ildbhost:-localhost}"
131
DB_PORT="${ildbport:-3306}"
132
DB="${ildb:-ilias}"
133
DB_USER="${ildbuser:-root}"
134
DB_PASSWORD="${ildbpassword:-}"
135

  
136
# Functions
137

  
138
autoconf() {
139
    if command -v "${DB_CLI_TOOL}" >/dev/null ; then
140
        echo yes
141
    else
142
        echo "no (failed to find executable '${DB_CLI_TOOL}')"
143
    fi
144
}
145

  
146
config() {
147
    local label_max_length=45
148
    local i=0
149

  
150
    # print global attributes
151
    echo "$global_attr" | sed -e 's/^  *//' -e '/^$/d'
152

  
153
    i=0
154
    # -v varname
155
    # True if the shell variable varname is set (has been assigned a value).
156
    # https://stackoverflow.com/a/45385463/2683737
157
    while [[ -v d_attr[$i,field] ]]; do
158
       field=${d_attr[$i,field]}
159
       echo "$field.type ${d_attr[$i,type]}"
160
       echo "$field.draw ${d_attr[$i,draw]}"
161
       echo "$field.label ${d_attr[$i,label]:0:${label_max_length}}"
162
       echo "$field.min 0"
163
       ((++i))
164
    done
165
}
166

  
167
# Join a bash array $1 is the glue
168
join_by() {
169
    local d=$1
170
    shift
171
    echo -n "$1"
172
    shift
173
    printf "%s" "${@/#/$d}"
174
}
175

  
176
fetch() {
177
    local i=0
178
    local query=()
179
    local query_string=""
180
    declare -a results
181

  
182
    # create an array of queries
183
    i=0
184
    while [[ -v d_attr[$i,field] ]]; do
185
        query+=("${d_attr[$i,sql]}")
186
        ((++i))
187
    done
188

  
189
    # build query by joining the array elements
190
    query_string=$(join_by " UNION ALL " "${query[@]}")
191

  
192
    # obtain result using CLI call; don't supply password through
193
    # command line; note that MySQL considers it insecure using
194
    # an environment variable:
195
    # >This method of specifying your MySQL password must
196
    # >be considered extremely insecure and should not be used.
197
    # >Some versions of ps include an option to display the
198
    # >environment of running processes. [...]
199
    result=$(MYSQL_PWD="$DB_PASSWORD" \
200
             "$DB_CLI_CMD" \
201
            --skip-column-names \
202
            -h "$DB_HOST" \
203
            -u "$DB_USER" \
204
            -P "$DB_PORT" \
205
            "$DB" \
206
            -e "$query_string" )
207

  
208
    # initialize array
209
    mapfile -t results  <<< "$result"
210

  
211
    # extract result and echo it to stdout, which is
212
    # captured by Munin
213
    i=0
214
    while [[ -v d_attr[$i,field] ]]; do
215
        echo "${d_attr[$i,field]}.value ${results[$i]}"
216
        ((++i))
217
    done
218
}
219

  
220

  
221
# Main
222
case ${1:-} in
223
autoconf)
224
    autoconf
225
    ;;
226
config)
227
    config
228
    [ "${MUNIN_CAP_DIRTYCONFIG:-}" = "1" ] && fetch
229
    ;;
230
*)
231
    fetch
232
    ;;
233
esac
234

  
235
exit 0
236

  

Formats disponibles : Unified diff