97 lines
3.1 KiB
Python
97 lines
3.1 KiB
Python
|
import re
|
||
|
import threading
|
||
|
import time
|
||
|
|
||
|
from flask import jsonify
|
||
|
from flask.blueprints import Blueprint
|
||
|
|
||
|
import websocket_routes
|
||
|
|
||
|
coreemu = None
|
||
|
_interface_regex = re.compile("\d+")
|
||
|
_throughput_thread = None
|
||
|
_thread_flag = True
|
||
|
|
||
|
api = Blueprint("throughput_api", __name__)
|
||
|
|
||
|
|
||
|
def get_net_stats():
|
||
|
with open("/proc/net/dev", "r") as net_stats:
|
||
|
data = net_stats.readlines()[2:]
|
||
|
|
||
|
stats = {}
|
||
|
for line in data:
|
||
|
line = line.strip()
|
||
|
if not line:
|
||
|
continue
|
||
|
line = line.split()
|
||
|
line[0] = line[0].strip(":")
|
||
|
stats[line[0]] = {"rx": float(line[1]), "tx": float(line[9])}
|
||
|
|
||
|
return stats
|
||
|
|
||
|
|
||
|
def throughput_collector(delay=3):
|
||
|
global _thread_flag
|
||
|
_thread_flag = True
|
||
|
last_check = None
|
||
|
last_stats = None
|
||
|
while _thread_flag:
|
||
|
now = time.time()
|
||
|
stats = get_net_stats()
|
||
|
|
||
|
# calculate average
|
||
|
if last_check is not None:
|
||
|
interval = now - last_check
|
||
|
bridges = []
|
||
|
interfaces = []
|
||
|
for key, current_rxtx in stats.iteritems():
|
||
|
previous_rxtx = last_stats.get(key)
|
||
|
if not previous_rxtx:
|
||
|
print "skipping %s, no previous value" % key
|
||
|
continue
|
||
|
rx_kbps = (current_rxtx["rx"] - previous_rxtx["rx"]) * 8.0 / interval
|
||
|
tx_kbps = (current_rxtx["tx"] - previous_rxtx["tx"]) * 8.0 / interval
|
||
|
throughput = rx_kbps + tx_kbps
|
||
|
print "%s - %s" % (key, throughput)
|
||
|
if key.startswith("veth"):
|
||
|
key = key.split(".")
|
||
|
node_id = int(_interface_regex.search(key[0]).group())
|
||
|
interface_id = int(key[1])
|
||
|
interfaces.append({"node": node_id, "interface": interface_id, "throughput": throughput})
|
||
|
elif key.startswith("b."):
|
||
|
node_id = key.split(".")[1]
|
||
|
bridges.append({"node": node_id, "throughput": throughput})
|
||
|
|
||
|
throughputs = {"bridges": bridges, "interfaces": interfaces}
|
||
|
websocket_routes.socketio.emit("throughput", throughputs)
|
||
|
# for interface in sorted(interfaces, key=lambda x: x["node"]):
|
||
|
# print "%s:%s - %s" % (interface["node"], interface["interface"], interface["throughput"])
|
||
|
# for bridge in sorted(bridges, key=lambda x: x["node"]):
|
||
|
# print "%s - %s" % (bridge["node"], bridge["throughput"])
|
||
|
|
||
|
last_check = now
|
||
|
last_stats = stats
|
||
|
time.sleep(delay)
|
||
|
|
||
|
|
||
|
@api.route("/throughput/start", methods=["PUT"])
|
||
|
def start_throughput():
|
||
|
global _throughput_thread
|
||
|
if not _throughput_thread:
|
||
|
_throughput_thread = threading.Thread(target=throughput_collector)
|
||
|
_throughput_thread.daemon = True
|
||
|
_throughput_thread.start()
|
||
|
return jsonify()
|
||
|
|
||
|
|
||
|
@api.route("/throughput/stop", methods=["PUT"])
|
||
|
def stop_throughput():
|
||
|
global _throughput_thread
|
||
|
global _thread_flag
|
||
|
if _throughput_thread:
|
||
|
_thread_flag = False
|
||
|
_throughput_thread.join()
|
||
|
_throughput_thread = None
|
||
|
return jsonify()
|