From 7f38d1421f7fd1ad6876fa41a9f1b7e8e896a9c8 Mon Sep 17 00:00:00 2001 From: nico Date: Thu, 18 Oct 2018 03:21:58 +0200 Subject: Initial Commit + added TeamSpeak Munin Plugin + general voice bandwidth + filetransfer bandwidth + usercount + uptime --- .gitignore | 127 +++++++++++++++++++++++++++++++++++++++ LICENCE.md | 13 ++++ teamspeak-multi.py | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 313 insertions(+) create mode 100644 .gitignore create mode 100644 LICENCE.md create mode 100644 teamspeak-multi.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..64562bd --- /dev/null +++ b/.gitignore @@ -0,0 +1,127 @@ +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +.idea/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +### Python Patch ### +.venv/ + +### Python.VirtualEnv Stack ### +# Virtualenv +# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ +[Bb]in +[Ii]nclude +[Ll]ib +[Ll]ib64 +[Ll]ocal +[Ss]cripts +pyvenv.cfg +pip-selfcheck.json 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/teamspeak-multi.py b/teamspeak-multi.py new file mode 100644 index 0000000..7a47dd8 --- /dev/null +++ b/teamspeak-multi.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Plugin to monitor a TeamSpeak Server via telnet +# * general bandwidth +# * filetransfer bandwidth +# * uptime +# +# 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 ts3 +import sys +import os + + +class TeamspeakMulti: + def config(self): + config = { + 'bandwidth': [ + 'multigraph teamspeak_transfer', + 'graph_order down up', + 'graph_title Teamspeak Transfer', + 'graph_args --base 1024', + 'graph_vlabel bits in (-) / out (+)', + 'graph_category voip', + 'graph_info This graph shows the Teamspeak3 Voice Bandwidth In and Out', + + 'down.label received', + 'down.info Bandwidth received in the last 5 minutes', + 'down.type DERIVE', + 'down.graph no', + 'down.min 0', + 'up.label sent', + 'up.info Bandwidth sent in the last 5 minutes', + 'up.type DERIVE', + 'up.negative down', + 'up.min 0', + ], + 'filetransfer': [ + 'multigraph teamspeak_fttransfer', + 'graph_order ftdown ftup', + 'graph_title Teamspeak File Bandwidth', + 'graph_args --base 1024', + 'graph_vlabel bits in (-) / out (+)', + 'graph_category voip', + 'graph_info This graph shows the Teamspeak3 File Bandwidth In and Out', + + 'ftdown.label received', + 'ftdown.info Bandwidth received in the last 5 minutes', + 'ftdown.type DERIVE', + 'ftdown.graph no', + 'ftdown.min 0', + 'ftup.label sent', + 'ftup.info Bandwidth sent in the last 5 minutes', + 'ftup.type DERIVE', + 'ftup.negative down', + 'ftup.min 0', + ], + 'uptime': [ + 'multigraph teamspeak_uptime', + 'graph_title Connected Teamspeak Users', + 'graph_args --base 1000 -l 0', + 'graph_scale no', + 'graph_vlabel uptime in days', + 'graph_category voip', + 'graph_info This graph shows the Teamspeak3 overall uptime', + + 'uptime.label uptime in seconds', + 'uptime.info TeamSpeak Server Uptime', + 'uptime.min 0', + 'uptime.draw AREA' + ], + 'users': [ + 'multigraph teamspeak_usercount', + 'graph_title TeamSpeak User Activity', + 'graph_args --base 1024 -l 0', + 'graph_printf %.0lf', + 'graph_vlabel connected users', + 'graph_info This graph shows the number of connected users on the Teamspeak3 server', + 'graph_category voip', + + 'user.label last 5 minutes', + 'user.info users connected in the last 5 minutes' + ] + } + + return config + + def get_data(self, response): + data ={ + 'teamspeak_transfer': [], + 'teamspeak_fttransfer': [], + 'teamspeak_uptime': [], + 'teamspeak_usercount': [] + } + + # transfer + data['teamspeak_transfer'].append('multigraph teamspeak_transfer') + data['teamspeak_transfer'].append('down.value %s ' % response["connection_bytes_received_total"]) + data['teamspeak_transfer'].append('up.value %s' % response["connection_bytes_sent_total"]) + + # fttransfer + data['teamspeak_fttransfer'].append('multigraph teamspeak_fttransfer') + data['teamspeak_fttransfer'].append('ftdown.value %s' % response["connection_filetransfer_bytes_received_total"]) + data['teamspeak_fttransfer'].append('ftup.value %s' % response["connection_filetransfer_bytes_sent_total"]) + + # uptime + data['teamspeak_uptime'].append('multigraph teamspeak_uptime') + uptime = int(response["instance_uptime"]) / 86400 + data['teamspeak_uptime'].append('uptime.value %s' % str(uptime)) + + # user count + data['teamspeak_usercount'].append('multigraph teamspeak_usercount') + data['teamspeak_usercount'].append('user.value %s' % response['virtualservers_total_clients_online']) + + return data + + def run(self): + # read the configuration from munin environment + server = (os.environ['host'], os.environ['port'], os.environ['id']) + auth = (os.environ['username'], os.environ['password']) + + with ts3.query.TS3Connection(server[0], server[1]) as ts3conn: + # will raise a TS3QueryError if response code is not 0 + try: + ts3conn.login( + client_login_name=auth[0], + client_login_password=auth[1], + ) + except ts3.query.TS3QueryError as err: + print("Login failed:", err.resp.error["msg"]) + exit(1) + + ts3conn.use(sid=server[2]) + hostinfo = ts3conn.hostinfo() + + info = hostinfo.parsed + result = self.get_data(info[0]) + + for key in result.keys(): + print('\n'.join(result[key])) + + def main(self): + if (sys.argv.__len__() == 2) and (sys.argv[1] == "config"): + for key in self.config().keys(): + print('\n'.join(self.config()[key])) + try: + if os.environ['MUNIN_CAP_DIRTYCONFIG'] == '1': + self.run() + except KeyError: + pass + + elif (sys.argv.__len__() == 2) and (sys.argv[1] == 'autoconf'): + # check host if env variables are set + try: + if None not in {os.environ['id'], os.environ['username'], os.environ['password']}: + print('yes') + except KeyError: + print('no env configuration options are missing') + else: + self.run() + + +if __name__ == "__main__": + TeamspeakMulti().main() + quit(0) -- cgit v1.2.3-54-g00ecf