101 lines
2.4 KiB
Python
101 lines
2.4 KiB
Python
import re
|
|
import sys
|
|
from collections import defaultdict
|
|
|
|
# ================= BACKEND FIX (IMPORTANT FOR HYPRLAND) =================
|
|
import matplotlib
|
|
|
|
try:
|
|
# Wayland / Hyprland recommended backend
|
|
matplotlib.use("QtAgg")
|
|
except Exception:
|
|
# fallback for headless systems
|
|
matplotlib.use("Agg")
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
# ================= INPUT =================
|
|
if len(sys.argv) < 2:
|
|
print("Usage: python analyze_log.py log.txt")
|
|
sys.exit(1)
|
|
|
|
logfile = sys.argv[1]
|
|
|
|
# ================= PARSE LOG =================
|
|
pattern = re.compile(r"(START|END).*TID=(\d+).*range=\[(\d+),(\d+)\].*time=([\d.]+)")
|
|
|
|
events = defaultdict(dict)
|
|
|
|
with open(logfile) as f:
|
|
for line in f:
|
|
m = pattern.search(line)
|
|
if not m:
|
|
continue
|
|
|
|
typ, tid, l, r, t = m.groups()
|
|
key = (tid, int(l), int(r))
|
|
events[key][typ] = float(t)
|
|
|
|
# ================= BUILD ROWS =================
|
|
rows = []
|
|
|
|
for (tid, l, r), v in events.items():
|
|
if "START" in v and "END" in v:
|
|
start = v["START"]
|
|
end = v["END"]
|
|
duration = end - start
|
|
|
|
rows.append(
|
|
{
|
|
"tid": tid,
|
|
"range": f"[{l},{r}]",
|
|
"start": start,
|
|
"end": end,
|
|
"duration": duration,
|
|
}
|
|
)
|
|
|
|
rows.sort(key=lambda x: x["start"])
|
|
|
|
if not rows:
|
|
print("No valid events found")
|
|
sys.exit(1)
|
|
|
|
# ================= OFFSET =================
|
|
t0 = rows[0]["start"]
|
|
|
|
for r in rows:
|
|
r["offset"] = r["start"] - t0
|
|
|
|
# ================= PRINT TABLE =================
|
|
print("\n## TABLE\n")
|
|
print("| TID | Range | Start | End | Duration | Offset |")
|
|
print("|-----|-------|-------|-----|----------|--------|")
|
|
|
|
for r in rows:
|
|
print(
|
|
f"| {r['tid']} | {r['range']} | "
|
|
f"{r['start']:.6f} | {r['end']:.6f} | "
|
|
f"{r['duration']:.6f} | {r['offset']:.6f} |"
|
|
)
|
|
|
|
# ================= PLOT =================
|
|
plt.figure(figsize=(10, 6))
|
|
|
|
for i, r in enumerate(rows):
|
|
plt.plot([r["offset"], r["offset"] + r["duration"]], [i, i], linewidth=4)
|
|
|
|
plt.xlabel("Time (seconds from start)")
|
|
plt.ylabel("Tasks")
|
|
plt.title("Execution Timeline")
|
|
plt.grid(True)
|
|
plt.tight_layout()
|
|
|
|
# ================= SAVE (IMPORTANT FOR LAB) =================
|
|
plt.savefig("timeline.png", dpi=200)
|
|
|
|
print("\nSaved: timeline.png")
|
|
|
|
# ================= SHOW (HYPRLAND WINDOW) =================
|
|
plt.show()
|