def __init__(self, name: str, args: List[str]): super().__init__(name, "kmt") self.args = self.__fix_args(args) self.kmt_out_path = None self.report["kmt"] = { "args": self.args, "cmdline": shlex_join(self.args), }
def _spawn(dest_dir, args, logname): logbase = os.path.join(dest_dir, logname) out = f"{logbase}.out" cmdline = f"{logbase}.cmdline" with open(cmdline, "w") as fd: fd.write(shlex_join(args)) fd.write("\n") fd = open(out, "w") proc = subprocess.Popen(args, stdout=fd, stderr=subprocess.STDOUT) return proc, fd
def _run_command(self, args, cwd=None, dest_dir=None, tool_name=None): if dest_dir is None: dest_dir = self.log_dir if tool_name is None: tool_name = self.tool_name os.makedirs(dest_dir, exist_ok=True) out_path = os.path.join(dest_dir, f"{tool_name}.out") cmdline_path = os.path.join(dest_dir, f"{tool_name}.cmdline") is_device_monitoring_enabled = config.is_device_monitoring_enabled() cmdline = shlex_join(args) with open(cmdline_path, "w") as fd: fd.write(cmdline) fd.write("\n") with ExitStack() as stack: print(cmdline) print(f"Output will be written to {out_path}") print() if is_device_monitoring_enabled: diskstats_before_path = save_diskstats(dest_dir, "BEFORE") save_kvdb_info(dest_dir, "BEFORE") fd = open(out_path, "w") stack.enter_context(fd) end_timestamp_ms = None start_timestamp_ms = int(time.time() * 1000) if self.start_timestamp_ms is None: self.start_timestamp_ms = start_timestamp_ms vmstat_proc, vmstat_fd = spawn_vmstat(dest_dir) stack.enter_context(vmstat_fd) stack.enter_context(vmstat_proc) if is_device_monitoring_enabled: iostat_proc, iostat_fd = spawn_iostat(dest_dir) stack.enter_context(iostat_fd) stack.enter_context(iostat_proc) # # now launching the main process # proc = subprocess.Popen(args, cwd=cwd, stdout=fd, stderr=subprocess.STDOUT) stack.enter_context(proc) pid = proc.pid pidstat_proc, pidstat_fd = spawn_pidstat(dest_dir, pid) stack.enter_context(pidstat_fd) stack.enter_context(pidstat_proc) returncode = proc.wait() vmstat_proc.kill() if is_device_monitoring_enabled: iostat_proc.kill() if returncode != 0: raise Exception( f"Command {args} failed with exit status {proc.returncode}" ) end_timestamp_ms = int(time.time() * 1000) self.end_timestamp_ms = end_timestamp_ms save_kvdb_info(dest_dir, "AFTER") if is_device_monitoring_enabled: diskstats_after_path = save_diskstats(dest_dir, "AFTER") diskstats_report = generate_diskstats_report( diskstats_before_path, diskstats_after_path ) if self.start_diskstats_before_path is None: self.start_diskstats_before_path = diskstats_before_path full_run_diskstats_report = generate_diskstats_report( self.start_diskstats_before_path, diskstats_after_path ) self.report["diskstats"] = full_run_diskstats_report["delta"] else: diskstats_report = None completed_info = CompletedCommand( start_timestamp_ms, end_timestamp_ms, out_path=out_path, diskstats=diskstats_report["delta"] if diskstats_report else None, ) return completed_info