收集机房出口流量

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('\n')):
                        ips.append(line.strip('\n'))
                    else:
                        print '%s is invalid ip address!' % line.strip('\n')
                        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 "\n%s transmit: %.3f Gb" % (self.ipfile, Gb)
            else:
                print "\n%s transmit: %.3f Mb" % (self.ipfile, Mb)
        else:
            print "\n%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:\n\t- %s iplist_file\n\t- %s single_ip\n""" % (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    = '\033[95m'
COLOR_BLUE    = '\033[94m'
COLOR_GREEN   = '\033[92m'
COLOR_YELLOW  = '\033[93m'
COLOR_RED     = '\033[91m'
COLOR_DEFAULT = '\033[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 = "===========================================================================================\n"
    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}\t".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}\t".format(idc)
            info += "{0:<15}{1:<15}".format(details[idc]['real'], details[idc]['threshold']) 
            info += "%.2f%%" % percent
        info += "\t\t{0}\n".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('\033[2J') which equals to `os.system('clear')`
        #os.system('clear')
        # 输出在原位置上刷新: 光标上移51行
        sys.stdout.write('\033[51A') # https://www.v2ex.com/t/292204
        output(result, details)
        print "\n%sRuntime is %s%s" % (COLOR_BLUE, time.time()-t_start, COLOR_DEFAULT)
        time.sleep(30)

  

 

posted @ 2018-02-01 19:39  lixin[at]hitwh  阅读(494)  评论(0编辑  收藏  举报