Skip to content

Instantly share code, notes, and snippets.

@zhouqiang-cl
Last active March 9, 2017 06:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save zhouqiang-cl/e718c7f5a6f9e07f400534d901d9e967 to your computer and use it in GitHub Desktop.
Save zhouqiang-cl/e718c7f5a6f9e07f400534d901d9e967 to your computer and use it in GitHub Desktop.
抓取一个网段的机器到另外一个网段的出入流量
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
@author: zhouqiang-cl@gmail.com
@date: 2016-12-12
抓取机器到另外一个机房的出入流量,并格式化输出. 包括到另外机房的每个ip的流量。
iftop 要使用较高的版本. centos 中建议 1.0pre4 以上.
"""
import subprocess
import socket
import json
import time
collect_cmd = 'sudo -i iftop -i em2 -b -t -s 11 -n'
def system(cmd):
'''
@summary: excute a subprocess return util subprocess stopped
@param cmd: a string that need to excute in subprocess
@result: return_code, stdout, stderr
'''
process = subprocess.Popen(
args=cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
std_out, std_err = process.communicate()
return_code = process.poll()
return return_code, std_out, std_err
def collect():
rt, std_out, stderr = system(collect_cmd)
if rt:
print "collect error, reason:%s\n %s" % (std_out, stderr)
return
else:
return std_out
def valid_ip(address):
try:
socket.inet_aton(address)
return True
except:
return False
def parser_iftop_stdout_to_pair(stdout):
start = True
end = False
pair_begin = start
tlines = []
ret = []
for line in stdout.split('\n'):
compute = False
try:
if valid_ip(line.split()[1]):
pair_begin = start
tlines.append(line)
compute = True
if not compute and valid_ip(line.split()[0]):
pair_begin = end
tlines.append(line)
source_line = False
if pair_begin == end:
if tlines:
ret.append(tlines)
tlines = []
except:
pass
return ret
def parser_flow_pair(pair):
val = {}
source = pair[0]
dest = pair[1]
source_ip = source.split()[1]
source_to_dist = source.split()[4]
dest_ip = dest.split()[0]
if not filter_ip(dest_ip):
return None
dist_to_source = dest.split()[3]
val["source"] = source_ip
val["dest"] = dest_ip
val["out"] = convert_to_bit(source_to_dist)
val["in"] = convert_to_bit(dist_to_source)
return val
def filter_ip(ip_addr):
if not ip_addr.startswith("10.19"):
return False
return True
def convert_to_bit(nbit):
if nbit.endswith("Kb"):
return float(nbit[0:-2])*1024
elif nbit.endswith("Mb"):
return float(nbit[0:-2])*1024*1024
else:
return float(nbit[0:-1])
def get_internal_ip():
return socket.getaddrinfo(socket.gethostname(), None)[0][-1][0]
def format_pairs(pairs):
output = []
item_out = {}
item_out["timestamp"] = int(time.time())
item_out["endpoint"] = socket.gethostname()
item_out["counterType"] = "GAUGE"
item_out["step"] = 60
item_out["tags"] = ""
item_out["metric"] = "network.out.total"
item_out["value"] = 0
item_in = item_out.copy()
item_in["metric"] = "network.in.total"
for pair in pairs:
item = {}
item["timestamp"] = int(time.time())
item["endpoint"] = socket.gethostname()
item["counterType"] = "GAUGE"
item["step"] = 60
item["tags"] = "ip=" + pair["dest"]
item["metric"] = "network.out"
item["value"] = int(pair["out"])
item_out["value"] += int(pair["out"])
output.append(item)
new_item = item.copy()
new_item["metric"] = "network.in"
new_item["value"] = int(pair["in"])
item_in["value"] += int(pair["in"])
output.append(new_item)
output.append(item_in)
output.append(item_out)
return json.dumps(output)
def main():
ip = get_internal_ip()
if filter_ip(ip):
return
std_out = collect()
raw_pairs = parser_iftop_stdout_to_pair(std_out)
pairs = []
for raw_pair in raw_pairs:
pair = parser_flow_pair(raw_pair)
if pair:
pairs.append(pair)
print format_pairs(pairs)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment