From cb7670a84ccef4283401a68271ab64e91e158dd8 Mon Sep 17 00:00:00 2001 From: nico Date: Wed, 12 Sep 2018 16:46:34 +0200 Subject: added Multigraph, Licence + added ICS Licence to repo + added multiggraph plugin variant with all features included + added nextcloud 14 pending app updates plugin * updated README.md * updated requests.sessions handeling to reduce keepalive sessions - removed keepalive header for all plugins --- LICENCE.md | 13 +++++ README.md | 26 +++++++-- nextcloud_apps | 70 ++++++++++++++++++++++ nextcloud_dbsize | 15 ++--- nextcloud_multi | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ nextcloud_shares | 15 ++--- nextcloud_users | 15 ++--- 7 files changed, 300 insertions(+), 27 deletions(-) create mode 100644 LICENCE.md create mode 100755 nextcloud_apps create mode 100755 nextcloud_multi diff --git a/LICENCE.md b/LICENCE.md new file mode 100644 index 0000000..e1fa701 --- /dev/null +++ b/LICENCE.md @@ -0,0 +1,13 @@ +Copyright (c) 2018 Nico Wellpott + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, 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. \ No newline at end of file diff --git a/README.md b/README.md index 45bf39c..267f9a8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Nextcloud Munin Plugin -Some basic Munin Plugins gathering information from the NextCloud external API. +Within this repository there are some basic Munin Plugins gathering information from the NextCloud external API. I choose to also include a multigraph plugin `nextcloud_multi` which does everything the other plugins do but in one single request. + +There are drawbacks to using a multigraph plugin which can be read up here : [Munin-Monitoring.org](http://guide.munin-monitoring.org/en/latest/plugin/multigraphing.html) ## install To use these plugins properly some configuration parameters need to be added to the plugin-config `/etc/munin/plugin-config.d/munin-node`. @@ -9,21 +11,33 @@ url = https://URL.TO.YOUR.NEXTCLOUD.tld/ocs/v2.php/apps/serverinfo/api/v1/info username = username password = password or logintoken ``` -After that the script needs to be placed in the munin plugin directory eg. `/etc/munin/plugins/` +To install these plugins, you just have to symlink those plugins you would like to activate to the munin plugin directory eg. `/etc/munin/plugins/`. Or if you want to use the multigraph plugin only symlink that one the the munin plugin directory. -The munin-node needs to be restarted to facilitate the new plugins. +After this has been done the munin-node needs to be restarted to facilitate the new plugins. `systemctl restart munin-node` ### everything working? -To check if everything is working as expected check if the plugins actually gather data. +To check if everything is working as expected check if the plugins are listed and actually gather data. ``` telnet localhost 4949 # localhost or IP the munin-node list fetch nextcloud_shares fetch nextcloud_users +fetch nextcloud_db +fetch nextcloud_apps +``` +If everything works as it should, list will return the symlinked plugins within the list of active plugins. + +##### multipgrah plugin +To check if the multigraph plugin is working correctly it is necessary to first instruct the capability multigraph before the `list` instruction. +``` +telnet localhost 4949 # localhost or IP the munin-node +cap multigraph +list +fetch nextcloud_multi ``` -If everything works as it should, list will return `nextcloud_shares` and `nextcloud_users` within the list of other active plugins. The `fetch` commands will run the script and return the gathered values. As long as none of them are NaN everything works as expected. +The `fetch` commands will run the script and return the gathered values. As long as none of them are NaN everything works as expected. ### uninstall -To remove the plugins from munin remove both plugins from the directory and restart the node. +To remove the plugins from munin remove all symlinked plugins from the directory and restart the node. diff --git a/nextcloud_apps b/nextcloud_apps new file mode 100755 index 0000000..574d932 --- /dev/null +++ b/nextcloud_apps @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Plugin to monitor the number of available nextcloud 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 + + +class NextcloudApps: + if (sys.argv.__len__() == 2) and (sys.argv[1] == "config"): + print('graph_title Nextcloud pending App updates') + print('graph_args --base 1024 -l 0') + print('graph_vlabel updates available') + print('graph_info graph showing the number of available app updates') + print('graph_category nextcloud') + + print('num_updates_available.label available app updates') + print('num_updates_available.info number of available app updates') + elif (sys.argv.__len__() == 2) and (sys.argv[1] == 'autoconf'): + # check host if env variables are set + try: + if None not in {os.environ['url'], os.environ['username'], os.environ['password']}: + print('yes') + except KeyError: + print('no env configuration options are missing') + else: + # read the configuration from munin environment + URL = os.environ['url'] + auth = (os.environ['username'], os.environ['password']) + + # init requests session with specific header and credentials + with requests.Session() as s: + s.auth = auth + s.headers.update({'Accept': 'application/json'}) + s.stream = False + + # request data from api + r = s.get(URL) + + # if status code is successful close connection and continue + if r.status_code == 200: + s.close() + api_response = r.json() + num_updates_available = api_response['ocs']['data']['nextcloud']['system']['apps']['num_updates_available'] + print('num_updates_available.value %s' % num_updates_available) + + 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') + + +if __name__ == "__main__": + NextcloudApps() + quit(0) diff --git a/nextcloud_dbsize b/nextcloud_dbsize index 7f0920d..986e658 100755 --- a/nextcloud_dbsize +++ b/nextcloud_dbsize @@ -1,12 +1,12 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# + # Plugin to monitor the nextcloud database size # # Parameters understood: # config (required) # autoconf (optional - used by munin-config) -# + # Magic markers - optional - used by installation scripts and # munin-config: # @@ -41,12 +41,13 @@ class NextcloudDB: auth = (os.environ['username'], os.environ['password']) # init requests session with specific header and credentials - s = requests.Session() - s.auth = auth - s.headers.update({'Accept': 'application/json'}) + with requests.Session() as s: + s.auth = auth + s.headers.update({'Accept': 'application/json'}) + s.stream = False - # request data from api - r = s.get(URL) + # request data from api + r = s.get(URL) # if status code is successful close connection and continue if r.status_code == 200: diff --git a/nextcloud_multi b/nextcloud_multi new file mode 100755 index 0000000..f0cfeeb --- /dev/null +++ b/nextcloud_multi @@ -0,0 +1,173 @@ +#!/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 APIExtract: + def __init__(self, result, api_repsonse): + self.api_response = api_repsonse + self.result = result + + def user_activity(self): + users = self.api_response['ocs']['data']['activeUsers'] + + self.result.append('multigraph nextcloud_users') + for key in users.keys(): + self.result.append(str(key) + ".value " + str(users[key])) + + return self.result + + def shares(self): + shares = self.api_response['ocs']['data']['nextcloud']['shares'] + + # use regex to remove permission stats from api response + reg = re.compile("num.*") + share_keys = shares.keys() + sharelist = list(filter(reg.match, share_keys)) + + self.result.append('multigraph nextcloud_shares') + for key in sharelist: + self.result.append(str(key) + ".value " + str(shares[key])) + + return self.result + + def dbsize(self): + dbsize = self.api_response['ocs']['data']['server']['database']['size'] + self.result.append('multigraph nextcloud_dbsize') + self.result.append('db_size.value %s' % dbsize) + + return self.result + + def apps(self): + num_updates_available = self.api_response['ocs']['data']['nextcloud']['system']['apps']['num_updates_available'] + self.result.append('multigraph nextcloud_apps') + self.result.append('num_updates_available.value %s' % num_updates_available) + + return self.result + + +class NextcloudMultiGraph: + if (sys.argv.__len__() == 2) and (sys.argv[1] == "config"): + print('multigraph nextcloud_users') + print('graph_title Nextcloud User Activity') + print('graph_args --base 1024 -l 0') + print('graph_printf %.0lf') + print('graph_vlabel connected users') + print('graph_info graph showing the number of connected user') + print('graph_category nextcloud') + + print('last5minutes.label last 5 minutes') + print('last5minutes.info users connected in the last 5 minutes') + print('last1hour.label last hour') + print('last1hour.info users connected in the last hour') + print('last24hours.label last 24 hours') + print('last24hours.info users connected in the last 24 hours') + + print('multigraph nextcloud_dbsize') + print('graph_title Nextcloud Database Size') + print('graph_args --base 1024 -l 0') + print('graph_vlabel size in byte') + print('graph_info graph showing the database size in byte') + print('graph_category nextcloud') + + print('db_size.label database size in byte') + print('db_size.info users connected in the last 5 minutes') + print('db_size.draw AREA') + + print('multigraph nextcloud_pending_updates') + print('graph_title Nextcloud pending App updates') + print('graph_args --base 1024 -l 0') + print('graph_vlabel updates pending') + print('graph_info graph showing the number of available app updates') + print('graph_category nextcloud') + + print('num_updates_available.label available app updates') + print('num_updates_available.info number of available app updates') + + print('multigraph nextcloud_shares') + print('graph_title Nextcloud Shares') + print('graph_args --base 1024 -l 0') + print('graph_vlabel number of shares') + print('graph_info graph showing the number of shares') + print('graph_category nextcloud') + + print('num_fed_shares_received.label federated shares recieved') + print('num_fed_shares_received.info current total of federated shares recieved') + print('num_fed_shares_sent.label federated shares sent') + print('num_fed_shares_sent.info current total of federated shares sent') + print('num_shares.label total number of shares') + print('num_shares.info current over all total of shares') + print('num_shares_groups.label group shares') + print('num_shares_groups.info current total of group shares') + print('num_shares_link.label link shares') + print('num_shares_link.info current total of shares through a link') + print('num_shares_link_no_password.label link shares without a password') + print('num_shares_link_no_password.info current total of shares through a link without a password protection') + print('num_shares_user.label user shares') + print('num_shares_user.info current total of user shares') + elif (sys.argv.__len__() == 2) and (sys.argv[1] == 'autoconf'): + # check host if env variables are set + try: + if None not in {os.environ['url'], os.environ['username'], os.environ['password']}: + print('yes') + except KeyError: + print('no env configuration options are missing') + else: + # read the configuration from munin environment + URL = os.environ['url'] + auth = (os.environ['username'], os.environ['password']) + + # init requests session with specific header and credentials + with requests.Session() as s: + s.auth = auth + s.headers.update({'Accept': 'application/json'}) + s.stream = False + + # request data from api + r = s.get(URL) + + # if status code is successful close connection and continue + if r.status_code == 200: + s.close() + api_response = r.json() + + result = list() + extract = APIExtract(result, api_response) + extract.user_activity() + extract.dbsize() + extract.shares() + extract.apps() + + print('\n'.join(result)) + 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') + + +if __name__ == "__main__": + NextcloudMultiGraph() + quit(0) diff --git a/nextcloud_shares b/nextcloud_shares index ba247d5..03462bd 100755 --- a/nextcloud_shares +++ b/nextcloud_shares @@ -1,12 +1,12 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# + # Plugin to monitor the amount shares to and from the specified nextcloud instance # # Parameters understood: # config (required) # autoconf (optional - used by munin-config) -# + # Magic markers - optional - used by installation scripts and # munin-config: # @@ -53,12 +53,13 @@ class NextcloudShares: auth = (os.environ['username'], os.environ['password']) # init requests session with specific header and credentials - s = requests.Session() - s.auth = auth - s.headers.update({'Accept': 'application/json'}) + with requests.Session() as s: + s.auth = auth + s.headers.update({'Accept': 'application/json'}) + s.stream = False - # request data from api - r = s.get(URL) + # request data from api + r = s.get(URL) # if status code is successful close connection and continue if r.status_code == 200: diff --git a/nextcloud_users b/nextcloud_users index eac5ae6..2230b84 100755 --- a/nextcloud_users +++ b/nextcloud_users @@ -1,12 +1,12 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# + # Plugin to monitor the amount of users sucessfully logging in to the specified nextcloud instance # # Parameters understood: # config (required) # autoconf (optional - used by munin-config) -# + # Magic markers - optional - used by installation scripts and # munin-config: # @@ -45,12 +45,13 @@ class NextcloudUsers: auth = (os.environ['username'], os.environ['password']) # init requests session with specific header and credentials - s = requests.Session() - s.auth = auth - s.headers.update({'Accept': 'application/json'}) + with requests.Session() as s: + s.auth = auth + s.headers.update({'Accept': 'application/json'}) + s.stream = False - # request data from api - r = s.get(URL) + # request data from api + r = s.get(URL) # if status code is successful close connection and continue if r.status_code == 200: -- cgit v1.2.3-18-g5258