# HG changeset patch # User Daniel O'Connor # Date 1420678060 -37800 # Node ID 8b5958404f81b2f86f409b7456199a626298bd72 # Parent e69ad89061dc2876d3ddffc8ab36f38a9c2de012 Add support for running as a munin plugin and a simple wrapper script. diff -r e69ad89061dc -r 8b5958404f81 adslstats.py --- a/adslstats.py Sat Feb 08 10:07:56 2014 +1030 +++ b/adslstats.py Thu Jan 08 11:17:40 2015 +1030 @@ -1,11 +1,11 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 ############################################################################ # # Parse ADSL link stats for Billion 7300G & generate RRD archives & graphs # ############################################################################ # -# Copyright (C) 2013 Daniel O'Connor. All rights reserved. +# Copyright (C) 2015 Daniel O'Connor. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -35,6 +35,7 @@ import os import re import rrdtool +import sys import time import urllib from bs4 import BeautifulSoup @@ -57,7 +58,9 @@ opts.add_option('-g', '--graph', action="store_true", default=False, help="Generate a graph") opts.add_option('-u', '--update', action="store_true", default=False, - help="Update RRD") + help="Update RRD (implies -d)") +opts.add_option('-m', '--munin', action="store", default=None, + help="Output munin data for ARG") opts.add_option('-a', '--authname', action="store", default=conf.get('global', 'username'), help="Username to login to modem") opts.add_option('-p', '--password', action="store", default=conf.get('global', 'password'), @@ -88,7 +91,6 @@ Attenuation - Up: %.1f dB, Down %.1f dB""" % (self.upstream, self.downstream, self.nmup, self.nmdown, self.attenup, self.attendown) - def getstats(f): s = BeautifulSoup(f) a = s.findAll('tr') @@ -117,7 +119,7 @@ # We expect data to be logged every 5 minutes # Average 12 5 minute points -> hourly stats (keep 168 - a weeks worth) # Average 288 5 minute points -> daily stats (keep 365 - a years worth) -# Detemine minimum & maximum for an hour and keep a weeks worth. +# Detemine minimum & maximum for an hour and keep a weeks worth. def makerrd(filename): rrdtool.create(filename, '--step', '300', @@ -143,20 +145,16 @@ stats.attenup, stats.attendown)) -# Open the URL and call the parser, the update the RRD -def doupdate(): +# Open the URL and call the parser +def getdata(): opener = urllib.FancyURLopener() opener.prompt_user_passwd = lambda host, realm: (options.authname, options.password) f = opener.open(statsurl) #f = open("adsl.html") stats = getstats(f) if stats == None: - if options.verbose: - print "Modem is offline" - return - if options.verbose: - print str(stats) - updaterrd(rrdname, int(time.time()), stats) + return None + return stats # Generate a graph def gengraph(): @@ -269,17 +267,74 @@ '--end', 'now', *signalargs) - if __name__ == "__main__": - if options.update: - try: - os.stat(rrdname) - except OSError, e: - if e.errno == 2: - print "rrd not found, creating.." - makerrd(rrdname) + names = ['Noise Margin (up)', 'Noise Margin (down)', 'Attenuation (up)', 'Attenuation (down)'] + if options.munin != None: + # Handle the wrapper passing us $0 directly + tmp = options.munin.split('_') + if len(tmp) > 1: + options.munin = tmp[-1] + if options.munin not in ['signal', 'sync']: + print "Unknown data type" + sys.exit(1) + if len(args) > 0: + if args[0] == 'config': + if options.munin == 'signal': + print '''graph_category adsl +graph_title ADSL Signal Quality +graph_args --base 1000 -l 0 +graph_vlabel dB''' + for n in names: + name = n.translate(None, ' ()').lower() + print '''%s.label %s +%s.type GAUGE +%s.max 100 +%s.min 0''' % (name, n, name, name, name) + elif options.munin == 'sync': + print '''graph_category adsl +graph_title ADSL Sync Speed +graph_args --base 1024 -l 0 +graph_vlabel kbit/sec +up.label Up +up.type GAUGE +up.max 24000 +up.min 0 +up.label Down +up.type GAUGE +up.max 24000 +up.min 0''' + sys.exit(0) + if options.update or options.munin: + stats = getdata() + if stats == None: + if options.verbose: + print "Modem is offline" - doupdate() + if stats != None: + if options.update: + try: + os.stat(rrdname) + except OSError, e: + if e.errno == 2: + print "rrd not found, creating.." + makerrd(rrdname) + + print '%d:%d:%d:%f:%f:%f:%f' % (int(time.time()), + stats.upstream, + stats.downstream, + stats.nmup, + stats.nmdown, + stats.attenup, + stats.attendown) + if options.munin != None: + if options.munin == 'signal': + print '''noisemarginup.value %.1f +noisemargindown.value %.1f +attenuationup.value %.1f +attenuationdown.value %.1f''' % (stats.nmup, stats.nmdown, stats.attenup, stats.attendown) + elif options.munin == 'sync': + print '''up.value %.1f +down.value %.1f''' % (stats.upstream, stats.downstream) if options.graph: gengraph() diff -r e69ad89061dc -r 8b5958404f81 muninplugin --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/muninplugin Thu Jan 08 11:17:40 2015 +1030 @@ -0,0 +1,11 @@ +#!/bin/sh + +# Create symlinks +# ln -fs /home/darius/projects/adslstats/muninplugin /usr/local/etc/munin/plugins/adslstats_signal +# ln -fs /home/darius/projects/adslstats/muninplugin /usr/local/etc/munin/plugins/adslstats_sync +# +# Add entry to /usr/local/etc/munin/plugin-conf.d/plugins.conf +# [adslstats_*] +# user darius + +/usr/local/bin/python2 /home/darius/projects/adslstats.dev/adslstats.py -m $0 $1