Renato Botelho do Couto | ead1e53 | 2019-10-31 13:31:07 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 2 | |
| 3 | import sys |
| 4 | import re |
| 5 | import argparse |
| 6 | import matplotlib.pyplot as plt |
| 7 | from matplotlib.lines import Line2D |
| 8 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 9 | |
| 10 | class Point: |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 11 | "CC event" |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 12 | |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 13 | def __init__(self, x, y): |
| 14 | self.x = x |
| 15 | self.y = y |
| 16 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 17 | |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 18 | def listx(points): |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 19 | return list(map(lambda pt: pt.x, points)) |
| 20 | |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 21 | |
| 22 | def listy(points): |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 23 | return list(map(lambda pt: pt.y, points)) |
| 24 | |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 25 | |
| 26 | def plot_data(d): |
| 27 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 28 | plt.figure(1) |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 29 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 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"]) |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 38 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 39 | # cwnd/ssthresh/cc events |
| 40 | plt.subplot(311) |
| 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") |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 47 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 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") |
| 53 | plt.legend( |
| 54 | (marker1, marker2, marker3, marker4, marker5), |
| 55 | ("cwnd", "ssthresh", "congestion", "recovered", "rxt-timeout"), |
| 56 | loc=4, |
| 57 | ) |
| 58 | axes = plt.gca() |
| 59 | axes.set_ylim([-20e4, max(cwndy) + 20e4]) |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 60 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 61 | # snd variables |
| 62 | plt.subplot(312) |
| 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) |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 70 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 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") |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 74 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 75 | # plt.plot(cwndx, d["snd_wnd"], 'ko', markersize=1) |
| 76 | plt.legend( |
| 77 | ( |
| 78 | "snd-space", |
| 79 | "flight", |
| 80 | "sacked", |
| 81 | "lost", |
| 82 | "cc-space", |
| 83 | "cwnd", |
| 84 | "congestion", |
| 85 | "recovered", |
| 86 | "rxt-timeout", |
| 87 | ), |
| 88 | loc=1, |
| 89 | ) |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 90 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 91 | # rto/srrt/rttvar |
| 92 | plt.subplot(313) |
| 93 | plt.title("rtt") |
| 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"]) |
| 98 | axes = plt.gca() |
| 99 | # plt.plot(cwndx, rto, 'r-') |
| 100 | # axes.set_ylim([0, int(max(rto[2:len(rto)])) + 50]) |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 101 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 102 | # show |
| 103 | plt.show() |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 104 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 105 | |
| 106 | def find_pattern(file_path, session_idx): |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 107 | is_active_open = 1 |
| 108 | listener_pattern = "l\[\d\]" |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 109 | if is_active_open: |
| 110 | initial_pattern = "\[\d\](\.\d+:\d+\->\.\d+:\d+)\s+open:\s" |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 111 | else: |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 112 | initial_pattern = "\[\d\](\.\d+:\d+\->\.\d+:\d+)\s" |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 113 | idx = 0 |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 114 | f = open(file_path, "r") |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 115 | for line in f: |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 116 | # skip listener lines (server) |
| 117 | if re.search(listener_pattern, line) != None: |
| 118 | continue |
| 119 | match = re.search(initial_pattern, line) |
| 120 | if match == None: |
| 121 | continue |
| 122 | if idx < session_idx: |
| 123 | idx += 1 |
| 124 | continue |
| 125 | filter_pattern = str(match.group(1)) + "\s+(.+)" |
| 126 | print("pattern is %s" % filter_pattern) |
| 127 | f.close() |
| 128 | return filter_pattern |
| 129 | raise Exception("Could not find initial pattern") |
| 130 | |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 131 | |
| 132 | def compute_time(min, sec, msec): |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 133 | return int(min) * 60 + int(sec) + int(msec) / 1000.0 |
| 134 | |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 135 | |
| 136 | def run(file_path, session_idx): |
| 137 | filter_sessions = 1 |
| 138 | filter_pattern = "" |
| 139 | |
| 140 | patterns = { |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 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", |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 149 | } |
| 150 | d = { |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 151 | "cwnd": [], |
| 152 | "space": [], |
| 153 | "flight": [], |
| 154 | "ssthresh": [], |
| 155 | "snd_wnd": [], |
| 156 | "cc-space": [], |
| 157 | "lost": [], |
| 158 | "sacked": [], |
| 159 | "rto": [], |
| 160 | "srtt": [], |
| 161 | "mrtt-us": [], |
| 162 | "rttvar": [], |
| 163 | "rxtTimeout": [], |
| 164 | "congestion": [], |
| 165 | "recovered": [], |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 166 | } |
| 167 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 168 | if filter_sessions: |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 169 | filter_pattern = find_pattern(file_path, session_idx) |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 170 | f = open(file_path, "r") |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 171 | |
| 172 | stats_index = 0 |
| 173 | start_time = 0 |
| 174 | |
| 175 | for line in f: |
| 176 | # skip listener lines (server) |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 177 | if re.search(patterns["listener"], line) != None: |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 178 | continue |
| 179 | # filter sessions |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 180 | if filter_sessions: |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 181 | match = re.search(filter_pattern, line) |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 182 | if match == None: |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 183 | continue |
| 184 | |
| 185 | original_line = line |
| 186 | line = match.group(1) |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 187 | match = re.search(patterns["time"], original_line) |
| 188 | if match == None: |
| 189 | print("something went wrong! no time!") |
| 190 | continue |
| 191 | time = compute_time(match.group(1), match.group(2), match.group(3)) |
| 192 | if start_time == 0: |
| 193 | start_time = time |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 194 | |
| 195 | time = time - start_time |
| 196 | match = re.search(patterns["cc"], line) |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 197 | if match != None: |
| 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))) |
| 203 | stats_index += 1 |
| 204 | continue |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 205 | match = re.search(patterns["cc-snd"], line) |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 206 | if match != None: |
| 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))) |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 210 | match = re.search(patterns["rtt"], line) |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 211 | if match != None: |
| 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))) |
| 216 | if stats_index == 0: |
| 217 | continue |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 218 | match = re.search(patterns["rxtt"], line) |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 219 | if match != None: |
| 220 | d["rxtTimeout"].append(Point(time, d["cwnd"][stats_index - 1].y + 1e4)) |
| 221 | continue |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 222 | match = re.search(patterns["congestion"], line) |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 223 | if match != None: |
| 224 | d["congestion"].append(Point(time, d["cwnd"][stats_index - 1].y - 1e4)) |
| 225 | continue |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 226 | match = re.search(patterns["recovered"], line) |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 227 | if match != None: |
| 228 | d["recovered"].append(Point(time, d["cwnd"][stats_index - 1].y)) |
| 229 | continue |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 230 | |
| 231 | plot_data(d) |
| 232 | |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 233 | |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 234 | if __name__ == "__main__": |
| 235 | parser = argparse.ArgumentParser(description="Plot tcp cc logs") |
Klement Sekera | d9b0c6f | 2022-04-26 19:02:15 +0200 | [diff] [blame^] | 236 | parser.add_argument( |
| 237 | "-f", action="store", dest="file", required=True, help="elog file in txt format" |
| 238 | ) |
| 239 | parser.add_argument( |
| 240 | "-s", |
| 241 | action="store", |
| 242 | dest="session_index", |
| 243 | default=0, |
| 244 | help="session index for which to plot cc logs", |
| 245 | ) |
Florin Coras | 3417d08 | 2019-06-12 08:12:58 -0700 | [diff] [blame] | 246 | results = parser.parse_args() |
| 247 | run(results.file, int(results.session_index)) |