6 import matplotlib.pyplot as plt
7 from matplotlib.lines import Line2D
13 def __init__(self, x, y):
19 return list(map(lambda pt: pt.x, points))
23 return list(map(lambda pt: pt.y, points))
30 cwndx = listx(d["cwnd"])
31 cwndy = listy(d["cwnd"])
32 congx = listx(d["congestion"])
33 congy = listy(d["congestion"])
34 rcvrdx = listx(d["recovered"])
35 rcvrdy = listy(d["recovered"])
36 rxttx = listx(d["rxtTimeout"])
37 rxtty = listy(d["rxtTimeout"])
39 # cwnd/ssthresh/cc events
41 plt.title("cwnd/ssthresh")
42 pcwnd = plt.plot(cwndx, cwndy, "r")
43 psst = plt.plot(cwndx, d["ssthresh"], "y-")
44 pcong = plt.plot(congx, congy, "yo")
45 precov = plt.plot(rcvrdx, rcvrdy, "co")
46 prxtt = plt.plot(rxttx, rxtty, "mo")
48 marker1 = Line2D(range(1), range(1), color="r")
49 marker2 = Line2D(range(1), range(1), color="y")
50 marker3 = Line2D(range(1), range(1), color="w", marker="o", markerfacecolor="y")
51 marker4 = Line2D(range(1), range(1), color="w", marker="o", markerfacecolor="c")
52 marker5 = Line2D(range(1), range(1), color="w", marker="o", markerfacecolor="m")
54 (marker1, marker2, marker3, marker4, marker5),
55 ("cwnd", "ssthresh", "congestion", "recovered", "rxt-timeout"),
59 axes.set_ylim([-20e4, max(cwndy) + 20e4])
63 plt.title("cc variables")
64 plt.plot(cwndx, d["space"], "g-", markersize=1)
65 plt.plot(cwndx, d["flight"], "b-", markersize=1)
66 plt.plot(cwndx, d["sacked"], "m:", markersize=1)
67 plt.plot(cwndx, d["lost"], "y:", markersize=1)
68 plt.plot(cwndx, d["cc-space"], "k:", markersize=1)
69 plt.plot(cwndx, cwndy, "ro", markersize=2)
71 plt.plot(congx, congy, "y^", markersize=10, markerfacecolor="y")
72 plt.plot(rcvrdx, rcvrdy, "c^", markersize=10, markerfacecolor="c")
73 plt.plot(rxttx, rxtty, "m^", markersize=10, markerfacecolor="m")
75 # plt.plot(cwndx, d["snd_wnd"], 'ko', markersize=1)
94 plt.plot(cwndx, d["srtt"], "g-")
95 plt.plot(cwndx, [x / 1000 for x in d["mrtt-us"]], "r-")
96 plt.plot(cwndx, d["rttvar"], "b-")
97 plt.legend(["srtt", "mrtt-us", "rttvar"])
99 # plt.plot(cwndx, rto, 'r-')
100 # axes.set_ylim([0, int(max(rto[2:len(rto)])) + 50])
106 def find_pattern(file_path, session_idx):
108 listener_pattern = "l\[\d\]"
110 initial_pattern = "\[\d\](\.\d+:\d+\->\.\d+:\d+)\s+open:\s"
112 initial_pattern = "\[\d\](\.\d+:\d+\->\.\d+:\d+)\s"
114 f = open(file_path, "r")
116 # skip listener lines (server)
117 if re.search(listener_pattern, line) != None:
119 match = re.search(initial_pattern, line)
122 if idx < session_idx:
125 filter_pattern = str(match.group(1)) + "\s+(.+)"
126 print("pattern is %s" % filter_pattern)
128 return filter_pattern
129 raise Exception("Could not find initial pattern")
132 def compute_time(min, sec, msec):
133 return int(min) * 60 + int(sec) + int(msec) / 1000.0
136 def run(file_path, session_idx):
141 "time": "^\d+:(\d+):(\d+):(\d+):\d+",
142 "listener": "l\[\d\]",
143 "cc": "cwnd (\d+) flight (\d+) space (\d+) ssthresh (\d+) snd_wnd (\d+)",
144 "cc-snd": "cc_space (\d+) sacked (\d+) lost (\d+)",
145 "rtt": "rto (\d+) srtt (\d+) mrtt-us (\d+) rttvar (\d+)",
146 "rxtt": "rxt-timeout",
147 "congestion": "congestion",
148 "recovered": "recovered",
169 filter_pattern = find_pattern(file_path, session_idx)
170 f = open(file_path, "r")
176 # skip listener lines (server)
177 if re.search(patterns["listener"], line) != None:
181 match = re.search(filter_pattern, line)
186 line = match.group(1)
187 match = re.search(patterns["time"], original_line)
189 print("something went wrong! no time!")
191 time = compute_time(match.group(1), match.group(2), match.group(3))
195 time = time - start_time
196 match = re.search(patterns["cc"], line)
198 d["cwnd"].append(Point(time, int(match.group(1))))
199 d["flight"].append(int(match.group(2)))
200 d["space"].append(int(match.group(3)))
201 d["ssthresh"].append(int(match.group(4)))
202 d["snd_wnd"].append(int(match.group(5)))
205 match = re.search(patterns["cc-snd"], line)
207 d["cc-space"].append(int(match.group(1)))
208 d["sacked"].append(int(match.group(2)))
209 d["lost"].append(int(match.group(3)))
210 match = re.search(patterns["rtt"], line)
212 d["rto"].append(int(match.group(1)))
213 d["srtt"].append(int(match.group(2)))
214 d["mrtt-us"].append(int(match.group(3)))
215 d["rttvar"].append(int(match.group(4)))
218 match = re.search(patterns["rxtt"], line)
220 d["rxtTimeout"].append(Point(time, d["cwnd"][stats_index - 1].y + 1e4))
222 match = re.search(patterns["congestion"], line)
224 d["congestion"].append(Point(time, d["cwnd"][stats_index - 1].y - 1e4))
226 match = re.search(patterns["recovered"], line)
228 d["recovered"].append(Point(time, d["cwnd"][stats_index - 1].y))
234 if __name__ == "__main__":
235 parser = argparse.ArgumentParser(description="Plot tcp cc logs")
237 "-f", action="store", dest="file", required=True, help="elog file in txt format"
242 dest="session_index",
244 help="session index for which to plot cc logs",
246 results = parser.parse_args()
247 run(results.file, int(results.session_index))