Mercurial > ~darius > hgwebdir.cgi > adslstats
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 |