core rest - added routes to parse throughput from /proc/net/dev and broadcast out over websocket
This commit is contained in:
parent
9b1bc3e444
commit
4c260c288e
4 changed files with 100 additions and 2 deletions
96
webapp/throughput_routes.py
Normal file
96
webapp/throughput_routes.py
Normal file
|
@ -0,0 +1,96 @@
|
|||
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()
|
Loading…
Add table
Add a link
Reference in a new issue