aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornico <nico@magicbroccoli.de>2018-10-18 03:21:58 +0200
committernico <nico@magicbroccoli.de>2018-10-18 03:21:58 +0200
commit7f38d1421f7fd1ad6876fa41a9f1b7e8e896a9c8 (patch)
treebde4dafaa1865a45a69c849104d60fd53c4418d9
Initial Commit
+ added TeamSpeak Munin Plugin + general voice bandwidth + filetransfer bandwidth + usercount + uptime
-rw-r--r--.gitignore127
-rw-r--r--LICENCE.md13
-rw-r--r--teamspeak-multi.py173
3 files changed, 313 insertions, 0 deletions
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 <nico@magicbroccoli.de>
+
+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)