Skip to content

Commit

Permalink
Add tquic_time_cwnd.py for analyzing TQUIC debug logs and produce a t…
Browse files Browse the repository at this point in the history
…ime-cwnd figure (#421)
  • Loading branch information
iyangsj authored Nov 7, 2024
1 parent 3c5cf77 commit 5804f34
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 6 deletions.
90 changes: 90 additions & 0 deletions tools/script/tquic_time_cwnd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env python3

# This tool is used to analyze TQUIC debug logs and produce a time-cwnd figure
# for the specified QUIC connection.

import re

from datetime import datetime
import argparse
import matplotlib.pyplot as plt


def parse_log(log_file, id):
with open(log_file, "r") as file:
log_data = file.readlines()

timestamps = []
inflights = []
cwnds = []

# Refine the regular expression to match timestamps and cwnds
timestamp_pattern = re.compile(r"\[(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3})Z")
cwnd_format = r"{} [a-zA-Z]* BEGIN_ACK inflight=(\d+) cwnd=(\d+)"
cwnd_pattern = re.compile(cwnd_format.format(id))

for line in log_data:
timestamp_match = timestamp_pattern.search(line)
if not timestamp_match:
continue

cwnd_match = cwnd_pattern.search(line)
if not cwnd_match:
continue

timestamp_str = timestamp_match.group(1)
timestamp = datetime.strptime(timestamp_str, "%Y-%m-%dT%H:%M:%S.%f")
inflight = int(cwnd_match.group(1))
cwnd = int(cwnd_match.group(2))
timestamps.append(timestamp)
inflights.append(inflight)
cwnds.append(cwnd)

return timestamps, inflights, cwnds


def plot_offsets(timestamps, inflights, cwnds, connection_path_id):
# Set output file name
ids = connection_path_id.split("-")
cid = ids[1]
pid = ids[2]
output_file_name = "tquic_time_cwnd_{}_{}.png".format(cid, pid)

plt.figure(figsize=(20, 6))
plt.plot(timestamps, inflights, label="inflight", linestyle="-", linewidth=0.5)
plt.plot(timestamps, cwnds, label="cwnd", linestyle="-", linewidth=0.5)
plt.xlabel("Time")
plt.ylabel("Cwnd/Inflight")
plt.title(f"Congestion window by Time in Connection {cid} Path {pid}")
plt.legend()
plt.gca().xaxis.set_major_formatter(
plt.matplotlib.dates.DateFormatter("%H:%M:%S.%f")
)
plt.savefig(output_file_name)
print("Found %d items, figure %s" % (len(timestamps), output_file_name))


if __name__ == "__main__":
# Set up the command line argument parser
parser = argparse.ArgumentParser(
description="Analyze TQUIC logs to get the relationship between cwnd/inflight and time."
)
parser.add_argument(
"-l",
"--log_file",
type=str,
help="path to the TQUIC debug log file",
required=True,
)
parser.add_argument(
"-c",
"--connection_path_id",
type=str,
help="connection path id, eg. SERVER-c6d45bc005585f42-0",
required=True,
)
args = parser.parse_args()

# Calling with command-line arguments
timestamps, inflights, cwnds = parse_log(args.log_file, args.connection_path_id)
plot_offsets(timestamps, inflights, cwnds, args.connection_path_id)
23 changes: 17 additions & 6 deletions tools/script/tquic_time_offset.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
import argparse
import matplotlib.pyplot as plt

STREAM_SEND_FORMAT=r"{} sent packet OneRTT.*?STREAM id={} off=(\d+) len=\d+ fin=(?:true|false)"
STREAM_RECV_FORMAT=r"{} recv frame STREAM id={} off=(\d+) len=\d+ fin=(?:true|false)"
STREAM_SEND_FORMAT = (
r"{} sent packet OneRTT.*?STREAM id={} off=(\d+) len=\d+ fin=(?:true|false)"
)
STREAM_RECV_FORMAT = r"{} recv frame STREAM id={} off=(\d+) len=\d+ fin=(?:true|false)"


def parse_log(log_file, cid, stream_id, recv):
with open(log_file, "r") as file:
Expand Down Expand Up @@ -68,21 +71,29 @@ def plot_offsets(timestamps, offsets, connection_trace_id, stream_id):
"-l",
"--log_file",
type=str,
help="Path to the TQUIC debug log file",
help="path to the TQUIC debug log file",
required=True,
)
parser.add_argument(
"-c",
"--connection_trace_id",
type=str,
help="Connection trace id, eg. SERVER-c6d45bc005585f42",
help="connection trace id, eg. SERVER-c6d45bc005585f42",
required=True,
)
parser.add_argument(
"-s", "--stream_id", type=int, help="Stream id, eg. 0", required=True
"-s",
"--stream_id",
type=int,
help="stream id (default 0), eg. 0",
default=0,
)
parser.add_argument(
"-r", "--recv", type=bool, help="Recv side instead of send side", default=False
"-r",
"--recv",
type=bool,
help="recv side instead of send side (default false)",
default=False,
)
args = parser.parse_args()

Expand Down

0 comments on commit 5804f34

Please sign in to comment.