nicer graph in 1

This commit is contained in:
2026-04-25 06:59:06 +07:00
parent dfe87e9b31
commit df31bae969
8 changed files with 113 additions and 78 deletions
+37 -11
View File
@@ -1,17 +1,22 @@
import os
import re
import sys
import matplotlib.pyplot as plt
OUT_DIR = "out"
os.makedirs(OUT_DIR, exist_ok=True)
LOG_RE = re.compile(
r"(PROC_START|PROC_END)\s+pid=(\d+)\s+ppid=(\d+)\s+depth=(\d+)\s+l=(\d+)\s+r=(\d+)\s+ts=([\d.]+)"
)
class Proc:
def __init__(self, pid, ppid):
def __init__(self, pid, ppid, depth):
self.pid = pid
self.ppid = ppid
self.depth = depth
self.start = None
self.end = None
self.children = []
@@ -23,18 +28,23 @@ class Proc:
def parse_log(path):
procs = {}
for line in open(path):
m = LOG_RE.search(line)
if not m:
continue
typ, pid, ppid, depth, l, r, ts = m.groups()
pid, ppid, ts = int(pid), int(ppid), float(ts)
pid, ppid, depth, ts = int(pid), int(ppid), int(depth), float(ts)
if pid not in procs:
procs[pid] = Proc(pid, ppid)
procs[pid] = Proc(pid, ppid, depth)
if typ == "PROC_START":
procs[pid].start = ts
else:
procs[pid].end = ts
return procs
@@ -61,37 +71,53 @@ def dfs_order(root):
def write_md(procs, ordered):
out_path = os.path.join(OUT_DIR, "processes.md")
first = min(p.start for p in procs.values())
with open("processes.md", "w") as f:
f.write("| PID | PPID | Start | End | Offset | Duration |\n")
f.write("|---|---|---|---|---|---|\n")
with open(out_path, "w") as f:
f.write("| PID | PPID | Depth | Start | End | Offset | Duration |\n")
f.write("|---|---|---|---|---|---|---|\n")
for p in ordered:
f.write(
f"| {p.pid} | {p.ppid} | {p.start:.6f} | {p.end:.6f} | {p.start - first:.6f} | {p.duration:.6f} |\n"
f"| {p.pid} | {p.ppid} | {p.depth} | "
f"{p.start:.6f} | {p.end:.6f} | "
f"{p.start - first:.6f} | {p.duration:.6f} |\n"
)
def draw_gantt(ordered):
out_path = os.path.join(OUT_DIR, "gantt.png")
first = min(p.start for p in ordered)
fig, ax = plt.subplots(figsize=(12, 6))
for i, p in enumerate(ordered):
ax.barh(i, p.duration, left=p.start - first, height=0.6)
ax.text(p.start - first, i, f" PID {p.pid}", va="center")
ax.text(p.start - first, i, f"PID {p.pid} ({p.depth})", va="center")
ax.set_yticks(range(len(ordered)))
ax.set_yticklabels([p.pid for p in ordered])
ax.set_yticklabels([f"{p.pid} ({p.depth})" for p in ordered])
ax.set_xlabel("Seconds from first process start")
ax.set_title("Process Gantt")
ax.set_title("Process Gantt (Tree + Depth)")
ax.invert_yaxis()
plt.tight_layout()
plt.savefig("gantt.png")
plt.savefig(out_path)
def main():
procs = parse_log(sys.argv[1])
root = build_tree(procs)
ordered = dfs_order(root)
write_md(procs, ordered)
draw_gantt(ordered)
print(f"Outputs saved to: {OUT_DIR}/")
if __name__ == "__main__":
main()