检测链路状态并画图

it2022-05-05  125

检测链路状态并画图 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib, urllib2 import os, sys, socket import datetime, time import json, re, subprocess import pycurl, cStringIO import threading import rrdtool from optparse import OptionParser MTR = [] SPEED = [] def get_m3u8_info(type, ip): params = urllib.urlencode({'unit': 'newusa', 'channel': 'CCTV1', 'type': type}) req = urllib2.urlopen('http://' + ip + '/approve/live?%s' % params) headers = req.info() rawdata = req.read() if ('Content-Encoding' in headers and headers['Content-Encoding']) or ('content-encoding' in headers and headers['content-encoding']): import gzip import StringIO data = StringIO.StringIO(rawdata) gz = gzip.GzipFile(fileobj=data) rawdata = gz.read() gz.close() urls = [] for line in rawdata.split('\n'): m = re.match('^http.*ts$', line) if m: urls.append(m.group(0)) return urls[0] def get_ts_file(name, url): buffer = cStringIO.StringIO() curl = pycurl.Curl() curl.setopt(pycurl.CONNECTTIMEOUT, 2) curl.setopt(pycurl.TIMEOUT, 10) curl.setopt(pycurl.NOSIGNAL, 1) curl.setopt(pycurl.URL, url) curl.setopt(pycurl.WRITEFUNCTION, buffer.write) try: curl.perform() download_speed = curl.getinfo(pycurl.SPEED_DOWNLOAD) SPEED.append((name, str(download_speed))) buffer.close() curl.close() except Exception, e: SPEED.append((name, 'U')) buffer.close() curl.close() class Quality(threading.Thread): def __init__(self, name, ip, count): threading.Thread.__init__(self) self.name = name self.ip = ip self.count = count def run(self): try: p = subprocess.Popen(['/usr/sbin/mtr', '-n', '-c', self.count, '-r', self.ip], stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = p.communicate() if output: info = output.split('\n')[-2] m = re.match('\s+\S+\s+\S+\s+(\S+)%\s+\S+\s+\S+\s+(\S+).*', info) if m: MTR.append((self.name, m.group(1), m.group(2))) else: MTR.append((self.name, 'U', 'U')) if error: print "ret> ", p.returncode print "Error> error ", error.strip() except OSError as e: print "OSError > ", e.errno print "OSError > ", e.strerror print "OSError > ", e.filename except: print "Error > ", sys.exc_info() def create_rrd(rrdfile, datasource): dss = [ 'DS:%s:GAUGE:120:0:U' % ds for ds in datasource.split(',') ] rra = [ 'RRA:AVERAGE:0.5:1:1440', 'RRA:AVERAGE:0.5:15:672', 'RRA:AVERAGE:0.5:60:744', 'RRA:AVERAGE:0.5:1440:375', 'RRA:MIN:0.5:1:1440', 'RRA:MIN:0.5:15:672', 'RRA:MIN:0.5:60:744', 'RRA:MIN:0.5:1440:375', 'RRA:MAX:0.5:1:1440', 'RRA:MAX:0.5:15:672', 'RRA:MAX:0.5:60:744', 'RRA:MAX:0.5:1440:375', 'RRA:LAST:0.5:1:1440', 'RRA:LAST:0.5:15:672', 'RRA:LAST:0.5:60:744', 'RRA:LAST:0.5:1440:375', ] rrdtool.create(rrdfile, '--step', '60', '--start', '-1y', dss, rra) def update_rrd(mode, datasource, timestamp): if mode == 'download': rrd_file = 'download.rrd' if not os.path.exists(rrd_file): create_rrd(rrd_file, datasource) labels = [] downloads = [] for label, download in SPEED: labels.append(label) downloads.append(download) rrdtool.update(rrd_file, '--template', ':'.join(labels), 'N:'+':'.join(downloads)) if mode == 'mtr': rrd_file_loss = 'loss.rrd' rrd_file_ping = 'ping.rrd' if not os.path.exists(rrd_file_loss): create_rrd(rrd_file_loss, datasource) if not os.path.exists(rrd_file_ping): create_rrd(rrd_file_ping, datasource) labels = [] losses = [] pings = [] for label, loss, ping in MTR: labels.append(label) losses.append(loss) pings.append(ping) rrdtool.update(rrd_file_loss, '--template', ':'.join(labels), 'N:'+':'.join(losses)) rrdtool.update(rrd_file_ping, '--template', ':'.join(labels), 'N:'+':'.join(pings)) def generate_graph_element(rrdfile, dss, unit): colors = ['#FFFF00', '#339933', '#FF6666', '#0066CC', '#FFFFFF'] comment = 'COMMENT: \\n' defs = [ 'DEF:%s=%s:%s:AVERAGE' % (ds, rrdfile, ds) for ds in dss.split(',') ] vdefs_min = [ 'VDEF:%s_min=%s,MINIMUM' % (ds, ds) for ds in dss.split(',') ] vdefs_max = [ 'VDEF:%s_max=%s,MAXIMUM' % (ds, ds) for ds in dss.split(',') ] vdefs_avg = [ 'VDEF:%s_avg=%s,AVERAGE' % (ds, ds) for ds in dss.split(',') ] vdefs_last = [ 'VDEF:%s_last=%s,LAST' % (ds, ds) for ds in dss.split(',') ] vdefs = [] for vdef in zip(vdefs_min, vdefs_max, vdefs_avg, vdefs_last): vdefs.extend(vdef) lines = [ 'LINE1:%s%s:%s' % (ds, colors[idx], ds) for idx, ds in enumerate(dss.split(',')) ] gprints_min = [ 'GPRINT:%s_min:MIN\:%%7.2lf %%s%s' % (ds, unit) for ds in dss.split(',') ] gprints_max = [ 'GPRINT:%s_max:MAX\:%%7.2lf %%s%s' % (ds, unit) for ds in dss.split(',') ] gprints_avg = [ 'GPRINT:%s_avg:AVERAGE\:%%7.2lf %%s%s' % (ds, unit) for ds in dss.split(',') ] gprints_last = [ 'GPRINT:%s_last:LAST\:%%7.2lf %%s%s' % (ds, unit) for ds in dss.split(',') ] gprints = [] for gprint in zip(lines, gprints_min, gprints_max, gprints_avg, gprints_last): gprints.extend(gprint) gprints.append(comment) return defs, vdefs, gprints def graph_rrd(hostname, names, dss): colors = [ \ '-c', 'SHADEA#000000', \ '-c', 'SHADEB#111111', \ '-c', 'FRAME#AAAAAA', \ '-c', 'FONT#FFFFFF', \ '-c', 'ARROW#FFFFFF', \ '-c', 'AXIS#FFFFFF', \ '-c', 'BACK#333333', \ '-c', 'CANVAS#333333', \ '-c', 'MGRID#CCCCCC', \ ] xgrid = 'MINUTE:10:MINUTE:30:MINUTE:30:0:%H:%M' for name in names.split(','): if name == 'download': label = 'Bytes' title = 'link_%s on %s' % (name, hostname) rrdfile = name + '.rrd' imgfile = name + '.png' defs, vdefs, gprints = generate_graph_element(rrdfile, dss, 'B') rrdtool.graph(imgfile, '-t', title, '-v', label, '-w', '520', '--start', '-3h', '--step', '60', '--x-grid', xgrid, colors, defs, vdefs, gprints) if name == 'loss': label = '%' title = 'link_%s on %s' % (name, hostname) rrdfile = name + '.rrd' imgfile = name + '.png' defs, vdefs, gprints = generate_graph_element(rrdfile, dss, '%%') rrdtool.graph(imgfile, '-t', title, '-v', label, '-w', '520', '--start', '-3h', '--step', '60', '--x-grid', xgrid, colors, defs, vdefs, gprints) if name == 'ping': label = 'ms' title = 'link_%s on %s' % (name, hostname) rrdfile = name + '.rrd' imgfile = name + '.png' defs, vdefs, gprints = generate_graph_element(rrdfile, dss, 'ms') rrdtool.graph(imgfile, '-t', title, '-v', label, '-w', '520', '--start', '-3h', '--step', '60', '--x-grid', xgrid, colors, defs, vdefs, gprints) if __name__ == '__main__': usage = '''%prog [options] arg1 arg2 example: . %prog --mode=download --name=wx-1-ct,wx-1-cu,wx-2-ct,wx-2-cu --ip=58.215.xx.xx,122.97.xx.xx,221.228.xx.xx,58.241.xx.xx --type=iptv . %prog --mode=mtr --name=wx-1-ct,wx-1-cu,wx-2-ct,wx-2-cu --ip=58.215.xx.xx,122.97.xx.xx,221.228.xx.xx,58.241.xx.xx --count=50 . %prog --mode=graph --name=download,loss,ping --ds=wx-1-ct,wx-1-cu,wx-2-ct,wx-2-cu ''' parser = OptionParser(usage) parser.add_option('--mode', action='store', type='string', dest='mode', help='check mode') parser.add_option('--name', action='store', type='string', dest='name', help='name list of the network link') parser.add_option('--ip', action='store', type='string', dest='ip', help='ip address list of the network link') parser.add_option('--type', action='store', type='string', dest='type', help='data rate of the ts file') parser.add_option('--count', action='store', type='string', dest='count', help='send packets per second') parser.add_option('--ds', action='store', type='string', dest='ds', help='data source') (options, args) = parser.parse_args() hostname = socket.gethostname() timestamp = int(time.time()) if options.mode == 'download': links = zip(options.name.split(','), options.ip.split(',')) for link in links: url = get_m3u8_info(options.type, link[1]) get_ts_file(link[0], url) update_rrd(options.mode, options.name, timestamp) if options.mode == 'mtr': links = zip(options.name.split(','), options.ip.split(',')) threads = [] for link in links: threads.append(Quality(link[0], link[1], options.count)) for t in threads: t.start() for t in threads: t.join() update_rrd(options.mode, options.name, timestamp) if options.mode == 'graph': graph_rrd(hostname, options.name, options.ds)

posted on 2016-07-21 12:11 北京涛子 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/liujitao79/p/5691289.html


最新回复(0)