82 lines
2.3 KiB
Python
82 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Parse Perf lines from a log file and plot sample mean, write mean, and loop mean over time."""
|
|
|
|
import sys
|
|
import re
|
|
import os
|
|
from datetime import datetime
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
PERF_RE = re.compile(
|
|
r"^(\w+ \d+ \d+:\d+:\d+) .* Perf\(.*?\):"
|
|
r".*?sample mean=([\d.]+)ms"
|
|
r".*?write mean=([\d.]+)ms"
|
|
r".*?loop mean=([\d.]+)ms"
|
|
)
|
|
|
|
|
|
def parse_log(log_path):
|
|
timestamps = []
|
|
sample_means = []
|
|
write_means = []
|
|
loop_means = []
|
|
|
|
with open(log_path, "r") as f:
|
|
for line in f:
|
|
m = PERF_RE.search(line)
|
|
if m:
|
|
ts_str, sample, write, loop = m.groups()
|
|
ts = datetime.strptime(ts_str, "%b %d %H:%M:%S")
|
|
timestamps.append(ts)
|
|
sample_means.append(float(sample))
|
|
write_means.append(float(write))
|
|
loop_means.append(float(loop))
|
|
|
|
if not timestamps:
|
|
print("No Perf lines found in the log file.", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
t0 = timestamps[0]
|
|
seconds = [(t - t0).total_seconds() for t in timestamps]
|
|
return seconds, sample_means, write_means, loop_means
|
|
|
|
|
|
def plot(seconds, sample_means, write_means, loop_means, out_path):
|
|
plt.figure(figsize=(12, 6))
|
|
plt.plot(seconds, sample_means, label="sample mean (ms)")
|
|
plt.plot(seconds, write_means, label="write mean (ms)")
|
|
plt.plot(seconds, loop_means, label="loop mean (ms)")
|
|
plt.xlabel("Time (s)")
|
|
plt.ylabel("Duration (ms)")
|
|
plt.title("Perf Metrics Over Time")
|
|
plt.legend()
|
|
plt.grid(True)
|
|
plt.tight_layout()
|
|
plt.savefig(out_path, dpi=150)
|
|
print(f"Plot saved to {out_path}")
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) != 2:
|
|
print(f"Usage: {sys.argv[0]} <path_to_log_file>", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
log_path = sys.argv[1]
|
|
if not os.path.isfile(log_path):
|
|
print(f"File not found: {log_path}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
seconds, sample_means, write_means, loop_means = parse_log(log_path)
|
|
|
|
log_dir = os.path.dirname(os.path.abspath(log_path))
|
|
log_base = os.path.splitext(os.path.basename(log_path))[0]
|
|
out_path = os.path.join(log_dir, f"{log_base}_perf_plot.png")
|
|
|
|
plot(seconds, sample_means, write_means, loop_means, out_path)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|