bw_agent.py
#!/usr/bin/python import time def get_bandwidth_info(): lines = open("/proc/net/dev", "r").readlines() columnLine = lines[1] _, receiveCols , transmitCols = columnLine.split("|") receiveCols = map(lambda a:"recv_"+a, receiveCols.split()) transmitCols = map(lambda a:"trans_"+a, transmitCols.split()) cols = receiveCols+transmitCols faces = {} for line in lines[2:]: if line.find(":") < 0: continue face, data = line.split(":") faceData = dict(zip(cols, data.split())) faces[face.strip()] = faceData if 'bond0' in faces: return int(faces['bond0']['trans_bytes']) if '0' != faces['eth1']['trans_bytes']: out = int(faces['eth1']['trans_bytes']) if '0' != faces['eth2']['trans_bytes']: out += int(faces['eth2']['trans_bytes']) return out if __name__ == '__main__': old_val = get_bandwidth_info() time.sleep(1) res = get_bandwidth_info() - old_val #res = round((val - old_val)/1024/1024,3) print res
bandwidth_watch.py
#!/usr/bin/python # -*- coding: UTF-8 -*- # Author: 71standby@gmail.com # Time: 2018-02-01 # Description: Show the vidc Transmit bandwidth. import os import re import sys import time import paramiko from multiprocessing import Pool #print multiprocessing.cpu_count() class Transmit(object): def __init__(self, ipfile, port=22, user='admin', key='/path/.ssh/known_hosts', timeout=5): self.ipfile = ipfile self.port = port self.user = user self.key = key self.timeout = timeout self.agent_file = 'bw_agent.py' self.remote_file = '/data/bw_agent.py' self.log_file = 'paramiko.log' self.cmd = 'python /data/bw_agent.py' self.counter = 0 def get_ips(self): if os.path.isfile(self.ipfile): ips = [] with open(self.ipfile) as iplist: content = iplist.readlines() for line in content: if line.startswith('#'): continue elif Transmit.check_ip(line.strip(' ')): ips.append(line.strip(' ')) else: print '%s is invalid ip address!' % line.strip(' ') continue return ips elif Transmit.check_ip(self.ipfile): return [ipfile] else: print '%s is invalid ip address!' % self.ipfile sys.exit(-1) def prepare(self, ip): paramiko.util.log_to_file (self.log_file) client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(ip, self.port, self.user, self.key, timeout=self.timeout) return client def scp_agent(self, ip, client): sftp = paramiko.SFTPClient.from_transport(client.get_transport()) sftp = client.open_sftp() sftp.put(self.agent_file, self.remote_file) def get_transmit(self, ip): res = {'ip':ip, 'result':None, 'code':None} try: client = self.prepare(ip) self.scp_agent(ip, client) chan = client.get_transport().open_session() chan.settimeout(self.timeout) chan.exec_command(self.cmd) res['code'] = chan.recv_exit_status() # chan.recv_ready() chan.recv_stderr_ready() chan.exit_status_ready() val = chan.recv(8192).strip() res['result'] = val if 0 == res['code'] else chan.recv_stderr(8192) except Exception, e: res['code'] = -1 res['result'] = 0 return res def callback(self, res): self.counter += 1 print "IP: %s, Transmit: %s" % (res.get('ip'), res.get('result', 0)) def statistics(self, res_list): sum = 0 for res in res_list: sum += int(res.get()['result']) # byte -> bit bits = float(sum*8) kb = bits / 1024 if kb >= 1024: Mb = kb / 1024 if Mb >= 1024: Gb = Mb / 1024 print " %s transmit: %.3f Gb" % (self.ipfile, Gb) else: print " %s transmit: %.3f Mb" % (self.ipfile, Mb) else: print " %s transmit: %.3f Kb" % (self.ipfile, kb) @staticmethod def check_ip(ip): ip_str = r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$' return True if re.match(ip_str, ip) else False ''' Attention: - PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed So, the run() method is need, like proxy. [https://strcpy.me/index.php/archives/318/] - paramiko.SSHClient().connect() parameter - client.connect('8.8.8.8', 22, 'admin', '/path/.ssh/known_hosts', timeout=5) is ok - client.connect('8.8.8.8', 22, 'admin', '/path/.ssh/known_hosts', 5) will raise exception: 'int' object has no attribute 'get_fingerprint' ''' def run(cls_instance, arg): return cls_instance.get_transmit(arg) if __name__ == '__main__': if 2 != len(sys.argv): print """Usage: - %s iplist_file - %s single_ip """ % (sys.argv[0],sys.argv[0]) sys.exit(-1) transmit = Transmit(sys.argv[1]) ips = transmit.get_ips() res_list = [] t_start = time.time() pool = Pool(20) for ip in ips: res = pool.apply_async(func=run, args=(transmit, ip,), callback=transmit.callback) res_list.append(res) pool.close() pool.join() # pool.terminate() transmit.statistics(res_list) print 'Dealt %d, Runtime is: %s' % (transmit.counter, (time.time()-t_start))
从接口获取数据,在终端上实时显示,在原位置刷新
#!/usr/bin/python # -*- coding: UTF-8 -*- # Author: 71standby@gmail.com # Time: 2018-02-11 # Description: Show the vidc Transmit bandwidth. import os import sys import json import time import signal import urllib2 from extra import bandwidth_info # print color COLOR_PINK = ' 33[95m' COLOR_BLUE = ' 33[94m' COLOR_GREEN = ' 33[92m' COLOR_YELLOW = ' 33[93m' COLOR_RED = ' 33[91m' COLOR_DEFAULT = ' 33[0m' def get_flow_info(url): '''从接口获取当前时刻机房出口带宽值''' try: response = urllib2.urlopen(url, timeout=10) return json.loads(response.read()) except Exception, e: print("urlopen error: %s" % e) def output(result, details): '''按照出口流量占比从高到低排序显示''' info = "=========================================================================================== " fd = sys.stdout result_li = sorted(result.items(), key=lambda x:x[1], reverse=True) for idc,percent in result_li: if percent > 90: info += "{0}{1:<20} ".format(COLOR_RED, idc) info += "{0:<15}{1:<15}".format(details[idc]['real'], details[idc]['threshold']) info += "%.2f%%%s" % (percent, COLOR_DEFAULT) else: info += "{0:<20} ".format(idc) info += "{0:<15}{1:<15}".format(details[idc]['real'], details[idc]['threshold']) info += "%.2f%%" % percent info += " {0} ".format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) sys.stdout.write(info) sys.stdout.flush() def handler(signal_num,frame): print "Bye..." sys.exit(0) if __name__ == '__main__': signal.signal(signal.SIGINT, handler) os.system('clear') result = {} details = {} realtime_api = "http://ip:port/path/to/interface" while True: t_start=time.time() ret_list = get_flow_info(realtime_api) for idc,threshold in bandwidth_info.core_idc_bw.items(): for item in ret_list: if item['name'] == idc: real = item['info']['flow'] result[idc] = float(real)/(threshold*1024)*100 details[idc] = {'real':real, 'threshold':threshold*1024} #sys.stdout.write(' 33[2J') which equals to `os.system('clear')` #os.system('clear') # 输出在原位置上刷新: 光标上移51行 sys.stdout.write(' 33[51A') # https://www.v2ex.com/t/292204 output(result, details) print " %sRuntime is %s%s" % (COLOR_BLUE, time.time()-t_start, COLOR_DEFAULT) time.sleep(30)