<<
path:
root/public/blog.git/html/bench/record.py
blob: a50035e935558978cda1a2acd901cccc3681a5c8
[raw]
[clear marker]
6from sys import exit, argv
8from pathlib import Path
11script_dir = Path(__file__).resolve().parent
13output_csv_fn = lambda a: f"metrics_{a}.csv"
14output_plot_fn = lambda a: f"plot_{a}.png"
17CSV_HEADER = "ts,cpu_percent,ram_mb,open_fds"
18GNUPLOT_FILE = script_dir / "plot_metrics.gp"
19DIR_CSV = Path("metrics")
20DIR_PLOT = Path("output")
24 create_new_file_or_exit(fp);
26 proc1, total1 = current_cpu(pid)
27 p = Path(f"/proc/{pid}")
29 num_cpus = open_file_or_exit("/proc/cpuinfo")
30 num_cpus = num_cpus.count("processor\t:")
35 proc2, total2 = current_cpu(pid)
36 total = total2 - total1
43 cpu_percent = 100 * (proc2 - proc1) / total * num_cpus
44 cpu_percent = round(cpu_percent, 1)
49 ram = open_file_or_exit(f"/proc/{pid}/status")
53 if line.startswith("VmRSS"):
55 mb = round(int(ram[1]) / 1024, 1)
58 fds = Path(f"/proc/{pid}/fd")
59 fds = len(listdir(fds))
61 ts = int(time.monotonic())
62 csv_line = f"{ts},{cpu_percent},{ram},{fds}"
65 line_append(fp, csv_line)
72 fields = open_file_or_exit(f"/proc/{pid}/stat")
73 fields = fields.split()
75 utime = int(fields[13])
76 stime = int(fields[14])
78 cpu_fields = open_file_or_exit("/proc/stat")
79 cpu_fields = cpu_fields.split("\n")[0].split()
81 total = sum(int(x) for x in cpu_fields[1:])
82 return utime + stime, total
85def open_file_or_exit(fp):
87 with open(fp, 'r', encoding="utf8") as f:
89 except Exception as e:
94def create_new_file_or_exit(fn):
96 with open(fn, "w+", encoding="utf8") as f:
97 f.write(CSV_HEADER + "\n")
98 except Exception as e:
103def line_append(fn, line):
105 with open(fn, "a+", encoding="utf8") as f:
107 except Exception as e:
114 subprocess.run(cmd, capture_output=True, text=True, check=True)
115 except subprocess.CalledProcessError as e:
116 print(f"Command failed {e.returncode}: {e.stderr}")
120if __name__ == "__main__":
123 if len(args) == 1 or len(args) > 4:
124 print("Usage: record.py PID [-p, -plot]")
127 DIR_CSV.mkdir(exist_ok=True)
128 DIR_PLOT.mkdir(exist_ok=True)
132 print("Need filepath to csv file")
137 out = Path(out).with_suffix(".png")
143 f"set output '{out}'",
146 run_command(gnuplot_cmd)
150 ts = int(time.monotonic())
151 fp = DIR_CSV / Path(output_csv_fn(f"{pid}_{ts}"))
152 out = DIR_PLOT / Path(output_plot_fn(f"{pid}_{ts}"))
156 except KeyboardInterrupt:
157 print("Terminated by user.")
165 f"set output '{out}'",
168 run_command(gnuplot_cmd)