core-extra/webapp/throughput_routes.py

97 lines
3.1 KiB
Python
Raw Normal View History

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()