1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Plugin to monitor nextcloud external api statistics
# * user activity
# * db size
# * share count
# * available app updates
#
# Parameters understood:
# config (required)
# autoconf (optional - used by munin-config)
# Magic markers - optional - used by installation scripts and
# munin-config:
#
# #%# family=manual
# #%# capabilities=autoconf
import requests
import sys
import os
import re
class NextcloudMultiGraph:
def config(self):
config = {
'users': [
'multigraph nextcloud_users',
'graph_title Nextcloud User Activity',
'graph_args --base 1000 -l 0',
'graph_printf %.0lf',
'graph_vlabel connected users',
'graph_info graph showing the number of connected user',
'graph_category nextcloud',
'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'
],
'shares': [
'multigraph nextcloud_shares',
'graph_title Nextcloud Shares',
'graph_args --base 1000 -l 0',
'graph_vlabel number of shares',
'graph_info graph showing the number of shares',
'graph_category nextcloud',
'num_fed_shares_received.label federated shares recieved',
'num_fed_shares_received.info current total of federated shares recieved',
'num_fed_shares_received.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_shares.label total number of shares',
'num_shares.info current over all total of shares',
'num_shares.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 shares through a link',
'num_shares_link.min 0',
'num_shares_link_no_password.label link shares without a password',
'num_shares_link_no_password.info current total of shares through a link without a password protection',
'num_shares_link_no_password.min 0',
'num_shares_user.label user shares',
'num_shares_user.info current total of user shares',
'num_shares_user.min 0'
],
'dbsize': [
'multigraph nextcloud_dbsize',
'graph_title Nextcloud Database Size',
'graph_args --base 1024 -l 0',
'graph_vlabel size in byte',
'graph_info graph showing the database size in byte',
'graph_category nextcloud',
'db_size.label database size in byte',
'db_size.info users connected in the last 5 minutes',
'db_size.draw AREA',
'db_size.min 0'
],
'available_updates': [
'multigraph nextcloud_available_updates',
'graph_title Nextcloud available App updates',
'graph_args --base 1000 -l 0',
'graph_vlabel updates available',
'graph_info graph showing the number of available app updates',
'graph_category nextcloud',
'num_updates_available.label available app updates',
'num_updates_available.info number of available app updates',
'num_updates_available.min 0'
]
}
return config
def get_data(self, api_response):
data ={
'nextcloud_users': [],
'nextcloud_shares': [],
'nextcloud_dbsize': [],
'nextcloud_available_updates': []
}
users = api_response['ocs']['data']['activeUsers']
shares = api_response['ocs']['data']['nextcloud']['shares']
dbsize = api_response['ocs']['data']['server']['database']['size']
data['nextcloud_users'].append('multigraph nextcloud_users')
for key in users.keys():
data['nextcloud_users'].append(str(key) + ".value " + str(users[key]))
# use regex to remove permission stats from api response
reg = re.compile("num.*")
share_keys = shares.keys()
sharelist = list(filter(reg.match, share_keys))
data['nextcloud_shares'].append('multigraph nextcloud_shares')
for key in sharelist:
data['nextcloud_shares'].append(str(key) + ".value " + str(shares[key]))
data['nextcloud_dbsize'].append('multigraph nextcloud_dbsize')
data['nextcloud_dbsize'].append('db_size.value %s' % dbsize)
# precaution for Nextcloud versions prior to version 14
version = api_response['ocs']['data']['nextcloud']['system']['version'].split(sep=".")
if int(version[0]) >= 14:
num_updates_available = api_response['ocs']['data']['nextcloud']['system']['apps']['num_updates_available']
data['nextcloud_available_updates'].append('num_updates_available.value %s' % num_updates_available)
return data
def run(self):
# init requests session with specific header and credentials
with requests.Session() as s:
# read credentials from env
s.auth = (os.environ.get('username'), os.environ.get('password'))
# update header for json
s.headers.update({'Accept': 'application/json'})
# request the data
r = s.get(os.environ.get('url'))
# if status code is successful continue
if r.status_code == 200:
api_response = r.json()
result = self.get_data(api_response)
for key in result.keys():
print('\n'.join(result[key]))
elif r.status_code == 996:
print('server error')
elif r.status_code == 997:
print('not authorized')
elif r.status_code == 998:
print('not found')
else:
print('unknown error')
def main(self):
# check if first argument is config or autoconf if not fetch data
if sys.argv.__len__() >= 2:
if sys.argv[1] == "config":
for key in self.config().keys():
print('\n'.join(self.config()[key]))
if os.environ.get('MUNIN_CAP_DIRTYCONFIG') == '1':
self.run()
elif sys.argv[1] == 'autoconf':
if None in [os.environ.get('username'), os.environ.get('password')]:
print('env variables are missing')
else:
print('yes')
else:
self.run()
if __name__ == "__main__":
NextcloudMultiGraph().main()
quit(0)
|