comparison adslstats.py @ 25:7571c101a4ee

Read options properly so it's usable by others
author Daniel O'Connor <darius@dons.net.au>
date Mon, 19 Jun 2017 10:02:30 +0930
parents 806b1ed7f1b5
children 04874587fb6e
comparison
equal deleted inserted replaced
24:806b1ed7f1b5 25:7571c101a4ee
35 import bs4 35 import bs4
36 import ConfigParser 36 import ConfigParser
37 import json 37 import json
38 import mechanize 38 import mechanize
39 import mysrp as srp 39 import mysrp as srp
40 import optparse 40 import argparse
41 import os 41 import os
42 import os.path 42 import os.path
43 import re 43 import re
44 import requests 44 import requests
45 import rrdtool 45 import rrdtool
47 import time 47 import time
48 import urllib 48 import urllib
49 49
50 conf = ConfigParser.ConfigParser() 50 conf = ConfigParser.ConfigParser()
51 conf.add_section('global') 51 conf.add_section('global')
52 conf.set('global', 'username', 'admin') 52
53 conf.set('global', 'password', 'admin') 53 conflist = []
54 conf.set('global', 'name', '10.0.2.14')
55 conf.set('global', 'cookiejar', os.path.expanduser('~/.adslstats.cj'))
56
57 conflist = ['adslstats.ini']
58 if ('HOME' in os.environ): 54 if ('HOME' in os.environ):
59 conflist.append(os.path.expanduser('~/.adslstats.ini')) 55 conflist.append(os.path.expanduser('~/.adslstats.ini'))
60 conf.read(conflist) 56 conf.read(conflist)
61 57
62 usage = '''%prog [options]''' 58 usage = '''%prog [options]'''
63 opts = optparse.OptionParser(usage) 59 parser = argparse.ArgumentParser(usage)
64 opts.add_option('-v', '--verbose', action="store_true", default=False, 60 parser.add_argument('-v', '--verbose', action='store_true', default=False,
65 help="Enable debug output") 61 help='Enable debug output')
66 opts.add_option('-g', '--graph', action="store_true", default=False, 62 parser.add_argument('-g', '--graph', action='store_true', default=False,
67 help="Generate a graph") 63 help='Generate a graph')
68 opts.add_option('-u', '--update', action="store_true", default=False, 64 parser.add_argument('-u', '--update', action='store_true', default=False,
69 help="Update RRD (implies -d)") 65 help='Update RRD (implies -d)')
70 opts.add_option('-m', '--munin', action="store", default=None, 66 parser.add_argument('-m', '--munin', action='store', default=None,
71 help="Output munin data for ARG") 67 help='Output munin data for ARG')
72 opts.add_option('-a', '--authname', action="store", default=conf.get('global', 'username'), 68 parser.add_argument('-a', '--username', action='store',
73 help="Username to login to modem") 69 help='Username to login to modem')
74 opts.add_option('-p', '--password', action="store", default=conf.get('global', 'password'), 70 parser.add_argument('-p', '--password', action='store',
75 help="Password to login to modem") 71 help='Password to login to modem')
76 opts.add_option('-n', '--name', action="store", default=conf.get('global', 'name'), 72 parser.add_argument('-n', '--name', action='store',
77 help="Hostname of modem") 73 help='Hostname of modem')
78 opts.add_option('-b', '--base', action="store", default="/home/darius/projects/adslstats/adslstats", 74 parser.add_argument('-b', '--base', action='store',
79 help="Base directory for RRD & PNGs") 75 help='Base directory for RRD & PNGs')
80 76 parser.add_argument('-c', '--cookiejar', action='store',
81 (options, args) = opts.parse_args() 77 help='Location of cookiejar')
82 78
83 rrdname = "%s.rrd" % (options.base) 79 args = parser.parse_args()
84 graphbasename = options.base 80
81 # Handle options from conf and override with ini
82 def opthelper(args, conf, optname):
83 if args.__getattribute__(optname) == None:
84 if not conf.has_option('global', optname):
85 parser.error(optname + ' must be specified in config file or via commandline')
86 else:
87 args.__setattr__(optname, conf.get('global', optname))
88
89 opthelper(args, conf, 'username')
90 opthelper(args, conf, 'password')
91 opthelper(args, conf, 'name')
92 opthelper(args, conf, 'base')
93 opthelper(args, conf, 'cookiejar')
94
95 # Expand path names
96 args.cookiejar = os.path.expanduser(args.cookiejar)
97 args.base = os.path.expanduser(args.base)
98
99 rrdname = "%s.rrd" % (args.base)
100 graphbasename = args.base
85 101
86 class DSLStats(object): 102 class DSLStats(object):
87 def __str__(self): 103 def __str__(self):
88 s = '''Line Rate - Up: %d kbits, Down %d kbits 104 s = '''Line Rate - Up: %d kbits, Down %d kbits
89 Maximum Rate - Up: %d kbit, Down %s kbit 105 Maximum Rate - Up: %d kbit, Down %s kbit
99 return s 115 return s
100 116
101 def getstats(): 117 def getstats():
102 stats = DSLStats() 118 stats = DSLStats()
103 parser = ConfigParser.ConfigParser() 119 parser = ConfigParser.ConfigParser()
104 base = 'http://%s' % (conf.get('global', 'name')) 120 base = 'http://%s' % (args.name)
105 br = mechanize.Browser() 121 br = mechanize.Browser()
106 #br.set_debug_http(True) 122 #br.set_debug_http(True)
107 #br.set_debug_responses(True) 123 #br.set_debug_responses(True)
108 #br.set_debug_redirects(True) 124 #br.set_debug_redirects(True)
109 cj = mechanize.LWPCookieJar() 125 cj = mechanize.LWPCookieJar()
110 if os.path.exists(conf.get('global', 'cookiejar')): 126 if os.path.exists(args.cookiejar):
111 cj.load(conf.get('global', 'cookiejar'), ignore_discard = True) 127 cj.load(args.cookiejar, ignore_discard = True)
112 br.set_cookiejar(cj) 128 br.set_cookiejar(cj)
113 if not fillstats(br, base, stats): 129 if not fillstats(br, base, stats):
114 if not authenticate(br, base, conf.get('global', 'username'), conf.get('global', 'password')): 130 if not authenticate(br, base, args.username, args.password):
115 print('login failed') 131 print('login failed')
116 return None 132 return None
117 print('login succeeded, getting stats') 133 #print('login succeeded, getting stats')
118 fillstats(br, base, stats) 134 fillstats(br, base, stats)
119 135
120 cj.save(conf.get('global', 'cookiejar'), ignore_discard = True) 136 cj.save(args.cookiejar, ignore_discard = True)
121 return stats 137 return stats
122 138
123 def authenticate(br, base, username, password): 139 def authenticate(br, base, username, password):
124 # Connect and authenticate 140 # Connect and authenticate
125 r = br.open(base) 141 r = br.open(base)
370 '--end', 'now', 386 '--end', 'now',
371 *signalargs) 387 *signalargs)
372 388
373 if __name__ == "__main__": 389 if __name__ == "__main__":
374 names = ['Noise Margin (up)', 'Noise Margin (down)', 'Attenuation (up)', 'Attenuation (down)'] 390 names = ['Noise Margin (up)', 'Noise Margin (down)', 'Attenuation (up)', 'Attenuation (down)']
375 if options.munin != None: 391 if args.munin != None:
376 # Handle the wrapper passing us its $0 as our $1 392 # Handle the wrapper passing us its $0 as our $1
377 tmp = options.munin.split('_') 393 tmp = args.munin.split('_')
378 if len(tmp) > 1: 394 if len(tmp) > 1:
379 options.munin = tmp[-1] 395 args.munin = tmp[-1]
380 if options.munin not in ['signal', 'sync']: 396 if args.munin not in ['signal', 'sync']:
381 print "Unknown data type ", options.munin 397 print "Unknown data type ", args.munin
382 sys.exit(1) 398 sys.exit(1)
383 if len(args) > 0: 399 if len(args) > 0:
384 if args[0] == 'config': 400 if args[0] == 'config':
385 if options.munin == 'signal': 401 if args.munin == 'signal':
386 print '''graph_category adsl 402 print '''graph_category adsl
387 graph_title DSL Signal Quality 403 graph_title DSL Signal Quality
388 graph_args --base 1000 -l 0 404 graph_args --base 1000 -l 0
389 graph_vlabel dB''' 405 graph_vlabel dB'''
390 for n in names: 406 for n in names:
391 name = n.translate(None, ' ()').lower() 407 name = n.translate(None, ' ()').lower()
392 print '''%s.label %s 408 print '''%s.label %s
393 %s.type GAUGE 409 %s.type GAUGE
394 %s.max 100 410 %s.max 100
395 %s.min 0''' % (name, n, name, name, name) 411 %s.min 0''' % (name, n, name, name, name)
396 elif options.munin == 'sync': 412 elif args.munin == 'sync':
397 print '''graph_category adsl 413 print '''graph_category adsl
398 graph_title DSL Sync Speed 414 graph_title DSL Sync Speed
399 graph_args --base 1024 -l 0 415 graph_args --base 1024 -l 0
400 graph_vlabel kbit/sec 416 graph_vlabel kbit/sec
401 up.label Up 417 up.label Up
413 downmax.label Down (max) 429 downmax.label Down (max)
414 downmax.type GAUGE 430 downmax.type GAUGE
415 downmax.max 150000 431 downmax.max 150000
416 downmax.min 0''' 432 downmax.min 0'''
417 sys.exit(0) 433 sys.exit(0)
418 if options.update or options.munin: 434 if args.update or args.munin:
419 stats = getdata() 435 stats = getdata()
420 if options.verbose: 436 if args.verbose:
421 if stats == None: 437 if stats == None:
422 print "Modem is offline" 438 print "Modem is offline"
423 else: 439 else:
424 print stats 440 print stats
425 if (options.update or options.munin != None) and stats != None: 441 if (args.update or args.munin != None) and stats != None:
426 if options.update: 442 if args.update:
427 try: 443 try:
428 os.stat(rrdname) 444 os.stat(rrdname)
429 except OSError, e: 445 except OSError, e:
430 if e.errno == 2: 446 if e.errno == 2:
431 print "rrd not found, creating.." 447 print "rrd not found, creating.."
432 makerrd(rrdname) 448 makerrd(rrdname)
433 updaterrd(rrdname, int(time.time()), stats) 449 updaterrd(rrdname, int(time.time()), stats)
434 if options.munin != None: 450 if args.munin != None:
435 if options.munin == 'signal': 451 if args.munin == 'signal':
436 print '''noisemarginup.value %.1f 452 print '''noisemarginup.value %.1f
437 noisemargindown.value %.1f 453 noisemargindown.value %.1f
438 attenuationup.value %.1f 454 attenuationup.value %.1f
439 attenuationdown.value %.1f''' % (stats.nmup, stats.nmdown, stats.attenup, stats.attendown) 455 attenuationdown.value %.1f''' % (stats.nmup, stats.nmdown, stats.attenup, stats.attendown)
440 elif options.munin == 'sync': 456 elif args.munin == 'sync':
441 s = '''up.value %.1f 457 s = '''up.value %.1f
442 down.value %.1f\n''' % (stats.upstream, stats.downstream) 458 down.value %.1f\n''' % (stats.upstream, stats.downstream)
443 if hasattr(stats, 'upstreammax'): 459 if hasattr(stats, 'upstreammax'):
444 s += '''upmax.value %.1f 460 s += '''upmax.value %.1f
445 downmax.value %.1f''' % (stats.upstreammax, stats.downstreammax) 461 downmax.value %.1f''' % (stats.upstreammax, stats.downstreammax)
446 print s 462 print s
447 if options.graph: 463 if args.graph:
448 gengraph() 464 gengraph()
449 465