forked from mininet/mininet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmonitor.py
More file actions
145 lines (126 loc) · 5.57 KB
/
monitor.py
File metadata and controls
145 lines (126 loc) · 5.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
from time import sleep, time
from subprocess import Popen, PIPE
from multiprocessing import Process
import re
import os
from mininet.log import info, error, debug, output
from mininet.util import quietRun
class Monitor(object):
def __init__(self, output_dir='/tmp'):
self.monitors = []
self.output_dir = output_dir
# Add general process monitors
# Bandwidth monitor
self.monitors.append(Process(target=self.monitor_devs_ng,
args=('%s/bwm.txt' % self.output_dir, 1.0)))
# CPU monitor
self.monitors.append(Process(target=self.monitor_cpu,
args=('%s/cpu.txt' % self.output_dir, )))
# cwnd monitor: tcp_probe
self.monitors.append(Process(target=self.monitor_cwnd,
args=('%s/tcp_probe.txt' % self.output_dir, )))
def start(self):
'''Start all the system monitors'''
# Set output directory
self.set_output_dir(self.output_dir)
# Start the monitors
for m in self.monitors:
m.start()
def stop(self):
'''Terminate all the system monitors'''
# Stop the monitors
for m in self.monitors:
m.terminate()
self.monitors = []
Popen("killall -9 bwm-ng top", shell=True).wait()
Popen("killall -9 cat; rmmod tcp_probe > /dev/null 2>&1;", shell=True).wait()
def set_output_dir(self, output_dir):
# Create output directory if it doesn't exist already
self.output_dir = output_dir
debug('Monitoring output dir: %s' % self.output_dir)
if not os.path.isdir(self.output_dir):
os.makedirs(self.output_dir)
def monitor_qlen(self, iface, interval_sec = 0.01, fname='%s/qlen.txt' % '.'):
pat_queued = re.compile(r'backlog\s[^\s]+\s([\d]+)p')
cmd = "tc -s qdisc show dev %s" % (iface)
ret = []
open(fname, 'w').write('')
while 1:
p = Popen(cmd, shell=True, stdout=PIPE)
output = p.stdout.read()
# Not quite right, but will do for now
matches = pat_queued.findall(output)
if matches and len(matches) > 1:
ret.append(matches[1])
t = "%f" % time()
open(fname, 'a').write(t + ',' + matches[1] + '\n')
sleep(interval_sec)
return
def monitor_cwnd(self, fname='%s/tcp_probe.txt' % '.'):
Popen("rmmod tcp_probe > /dev/null 2>&1; modprobe tcp_probe;", shell=True).wait()
Popen("cat /proc/net/tcpprobe > %s" % fname, shell=True).wait()
def monitor_devs_ng(self, fname="%s/txrate.txt" % '.', interval_sec=0.01):
"""Uses bwm-ng tool to collect iface tx rate stats. Very reliable."""
cmd = "sleep 1; bwm-ng -t %s -o csv -u bits -T rate -C ',' > %s" % (interval_sec * 1000, fname)
Popen(cmd, shell=True).wait()
def monitor_cpu(self, fname="%s/cpu.txt" % '.'):
cmd = "(top -b -p 1 -d 1 | grep --line-buffered \"^Cpu\") > %s" % fname
Popen(cmd, shell=True).wait()
def monitor_cpuacct(self, hosts, fname="%s/cpuacct.txt" % '.', interval_sec=1.0):
prereqs = ['cgget']
for p in prereqs:
if not quietRun('which ' + p):
error('Could not find %s... not monitoring cpuacct' % p)
return
hnames = ' '.join([h.name for h in hosts])
cpuacct_cmd = 'cgget -g cpuacct %s >> %s' % (hnames, fname)
prev_time = time()
while 1:
sleep(interval_sec - (time() - prev_time))
prev_time = time()
cpu_usage = Popen(cpuacct_cmd, shell=True).wait()
return
# Obsolete: Use bwm-ng instead (monitor_devs_ng), for reliable stats
def monitor_count(self, ipt_args="--src 10.0.0.0/8", interval_sec=0.01, fname='%s/bytes_sent.txt' % '.', chain="OUTPUT"):
cmd = "iptables -I %(chain)s 1 %(filter)s -j RETURN" % {
"filter": ipt_args,
"chain": chain,
}
# We always erase the first rule; will fix this later
Popen("iptables -D %s 1" % chain, shell=True).wait()
# Add our rule
Popen(cmd, shell=True).wait()
open(fname, 'w').write('')
cmd = "iptables -vnL %s 1 -Z" % (chain)
while 1:
p = Popen(cmd, shell=True, stdout=PIPE)
output = p.stdout.read().strip()
values = output.split(' ')
if len(values) > 2:
t = "%f" % time()
pkts, bytes = values[0], values[1]
open(fname, 'a').write(','.join([t, pkts, bytes]) + '\n')
sleep(interval_sec)
return
# Obsolete: Use bwm-ng instead (monitor_devs_ng), for reliable stats
def monitor_devs(self, dev_pattern='^sw', fname="%s/bytes_sent.txt" % '.', interval_sec=0.01):
"""Aggregates (sums) all txed bytes and rate (in Mbps) from devices whose name
matches @dev_pattern and writes to @fname"""
pat = re.compile(dev_pattern)
spaces = re.compile('\s+')
open(fname, 'w').write('')
prev_tx = {}
while 1:
lines = open('/proc/net/dev').read().split('\n')
t = str(time())
total = 0
for line in lines:
line = spaces.split(line.strip())
iface = line[0]
if pat.match(iface) and len(line) > 9:
tx_bytes = int(line[9])
total += tx_bytes - prev_tx.get(iface, tx_bytes)
prev_tx[iface] = tx_bytes
open(fname, 'a').write(','.join([t, str(total * 8 / interval_sec / 1e6), str(total)]) + "\n")
sleep(interval_sec)
return