import os import re import sys from collections import defaultdict import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt if len(sys.argv) < 3: print("Использование: python3 exporter.py ") sys.exit(1) logfile = sys.argv[1] out_dir = sys.argv[2] os.makedirs(out_dir, exist_ok=True) base = os.path.splitext(os.path.basename(logfile))[0] pattern = re.compile( r"(START|END) PID=(\d+) PPID=(\d+) depth=(\d+) size=(\d+) time=([\d.]+)" ) events = defaultdict(dict) with open(logfile, encoding="utf-8") as f: for line in f: m = pattern.search(line) if not m: continue typ, pid, ppid, depth, size, t = m.groups() key = (int(pid), int(depth), int(size)) events[key][typ] = float(t) events[key]["pid"] = int(pid) events[key]["ppid"] = int(ppid) events[key]["depth"] = int(depth) events[key]["size"] = int(size) rows = [] for v in events.values(): if "START" in v and "END" in v: rows.append(v) if not rows: print("В логе нет полных START/END событий") sys.exit(1) rows.sort(key=lambda r: (r["START"], r["depth"], r["pid"])) t0 = min(r["START"] for r in rows) # 1. Временная диаграмма: видно параллельность и время жизни каждого процесса. plt.figure(figsize=(12, max(5, len(rows) * 0.35))) for y, r in enumerate(rows): start = r["START"] - t0 end = r["END"] - t0 plt.plot([start, end], [y, y], linewidth=5) plt.text( end, y, f" pid={r['pid']} d={r['depth']} n={r['size']}", va="center", fontsize=8, ) plt.xlabel("Время от начала, сек") plt.ylabel("Процессы/задачи сортировки") plt.title(f"Временная диаграмма процессов: {base}") plt.grid(True) plt.tight_layout() plt.savefig(os.path.join(out_dir, f"{base}_timeline.png")) plt.close() # 2. Гистограмма глубин: проверка, что дерево дошло до нужной глубины. by_depth = defaultdict(int) for r in rows: by_depth[r["depth"]] += 1 plt.figure(figsize=(8, 5)) xs = sorted(by_depth) plt.bar(xs, [by_depth[x] for x in xs]) plt.xlabel("Глубина рекурсии") plt.ylabel("Количество процессов") plt.title(f"Распределение процессов по глубине: {base}") plt.grid(True, axis="y") plt.tight_layout() plt.savefig(os.path.join(out_dir, f"{base}_depth_hist.png")) plt.close()