def test_datetime(self): tracer = viztracer.VizTracer() tracer.start() from datetime import timedelta timedelta(hours=5) tracer.stop() tracer.parse() tracer.generate_json() tracer = viztracer.VizTracer(tracer="python") tracer.start() from datetime import timedelta timedelta(hours=5) tracer.stop() tracer.parse() tracer.generate_json()
def run(self): import os import viztracer import signal import atexit def exit_routine(): atexit.unregister(exit_routine) if not self._exiting: self._exiting = True tracer = viztracer.get_tracer() tracer.stop() tracer.save() tracer.terminate() exit(0) def term_handler(signalnum, frame): exit_routine() atexit.register(exit_routine) signal.signal(signal.SIGTERM, term_handler) tracer = viztracer.VizTracer(**self._viztracer_kwargs) tracer.start() tracer.pid_suffix = True tracer.output_file = os.path.join(self._multiprocess_output_dir, "result.json") self._run()
def test_datetime(self): tracer = viztracer.VizTracer() tracer.start() from datetime import timedelta timedelta(hours=5) tracer.stop() tracer.parse() tracer.save(output_file="tmp.json") tracer = viztracer.VizTracer() tracer.start() from datetime import timedelta timedelta(hours=5) tracer.stop() tracer.parse() tracer.save(output_file="tmp.json") os.remove("tmp.json")
def main(argv=sys.argv): parser = argparse.ArgumentParser(argv[0], formatter_class=argparse.RawDescriptionHelpFormatter, usage=usage) parser.add_argument('--module', '-m') parser.add_argument('--import', dest="import_", help="Comma seperated list of modules to import before tracing (cleans up tracing output)") parser.add_argument('--verbose', '-v', action='count', default=1) parser.add_argument('--quiet', '-q', action='count', default=0) parser.add_argument('--output', '-o', dest="output", help="Output filename (default %(default)s)", default='perf.data') parser.add_argument('--output-viztracer', help="Output filename for viztracer (default %(default)s)", default='viztracer.json') parser.add_argument('--freq', '-F', help="Profile frequency, passed down to perf record (see man perf record)") parser.add_argument('--event', '-e', dest='events', help="Select PMU event, passed down to perf record (see man perf record)", action='append', default=[]) parser.add_argument('--tracer_entries', type=int, default=1000000, help="See viztracer --help") # # these gets passed to stacktraceinject # parser.add_argument('--keep-cpython-evals', help="keep CPython evaluation stacktraces (instead of replacing) (default: %(default)s)", default=True, action='store_true') # parser.add_argument('--no-keep-cpython-evals', dest="keep_cpython_evals", action='store_false') # parser.add_argument('--allow-mismatch', help="Keep going even when we cannot match the C and Python stacktrace (default: %(default)s)", default=False, action='store_true') # parser.add_argument('--no-allow-mismatch', dest="allow_mismatch", action='store_false') # parser.add_argument('--pedantic', help="If false, accept known stack mismatch issues (default: %(default)s)", default=False, action='store_true') # parser.add_argument('--no-pedantic', dest="pedantic", action='store_false') parser.add_argument('args', nargs=argparse.REMAINDER) args = parser.parse_args(argv[1:]) verbose = args.verbose - args.quiet if args.import_: for module in args.import_.split(','): if verbose >= 2: print(f'importing {module}') __import__(module) viztracer_path = args.output_viztracer ctx = contextlib.redirect_stdout(None) if verbose == 0 else empty_context() perf_args = [] if args.freq: perf_args.append(f' --freq={args.freq}') for event in args.events: perf_args.append(f' -e {event}') with ctx: with PerfRecord(verbose=verbose, args=perf_args) as perf: with viztracer.VizTracer(output_file=viztracer_path, verbose=verbose, tracer_entries=args.tracer_entries): if args.module: runpy.run_module(args.module) else: sys.argv = args.args runpy.run_path(sys.argv[0])
def viztracer_profile( path: Union[Callable[[], str], str], max_stack_depth: int = -1, ): try: import viztracer # pylint: disable=import-error except ImportError: print("Failed to run profiler, viztracer is not installed") yield return tracer = viztracer.VizTracer(max_stack_depth=max_stack_depth) tracer.start() yield tracer.stop() tracer.save(path() if callable(path) else path)
def giltracer(self, line, cell, local_ns): temp_dir = tempfile.mkdtemp() perf_path = os.path.join(temp_dir, 'perf.data') viz_path = os.path.join(temp_dir, 'viztracer.json') gil_path = os.path.join(temp_dir, 'giltracer.json') out_path = 'giltracer.html' code = self.shell.transform_cell(cell) with PerfRecordGIL(perf_path, gil_path) as gt: with viztracer.VizTracer(output_file=viz_path): exec(code, local_ns, local_ns) gt.post_process() builder = ReportBuilder([viz_path, gil_path]) builder.save(output_file=out_path) download = HTML( f'''<a href="{out_path}" download>Download {out_path}</a>''') view = HTML( f'''<a href="{out_path}" target="_blank" rel="noopener noreferrer">Open {out_path} in new tab</a> (might not work due to security issue)''' ) display(download, view)
async def start(self, scheduler: distributed.Scheduler) -> None: self.scheduler = scheduler self._tempfile = tempfile.NamedTemporaryFile( suffix=f"viztracer.{self.format}") if self._HANDLER_NAME in scheduler.handlers: raise RuntimeError( "A viztracer plugin is already registered: " f"{scheduler.handlers[self._HANDLER_NAME]} vs {self._get_profile}!" ) else: scheduler.handlers[self._HANDLER_NAME] = self._get_profile self.tracer = viztracer.VizTracer(output_file=self._tempfile.name, **self.kwargs) # NOTE: this has to come after the tracer is instantiated, so `get_tracer()` works within `log_sparse` self.log_sparse_unpatchers = [ add_decorator(name, scheduler, viztracer.log_sparse) for name in self.patch_log_sparse_names ] self.trace_sparse_unpatchers = [ add_decorator(name, scheduler, trace_sparse) for name in self.patch_trace_sparse_names ] if self.tracer.log_sparse: if self.patch_trace_sparse_names: # HACK: to make `trace_sparse` work, the tracer must have already been started. otherwise, # https://github.com/gaogaotiantian/viztracer/blob/1c7080b61f2/src/viztracer/modules/snaptrace.c#L583 # segfaults since `cur_tracer` is NULL. # (`cur_tracer` in the C extension != `register_global` at the Python level!) # TODO contribute `trace_sparse` upstream to viztracer self.tracer.start() self.tracer.pause() else: # this is how `log_sparse` is implemented: # https://github.com/gaogaotiantian/viztracer/blob/1c7080b61f/src/viztracer/main.py#L239-L244 self.tracer.enable = True else: self.tracer.start()
def main(argv=sys.argv): parser = argparse.ArgumentParser( argv[0], formatter_class=argparse.RawDescriptionHelpFormatter, usage=usage) parser.add_argument('--module', '-m') parser.add_argument( '--import', dest="import_", help= "Comma seperated list of modules to import before tracing (cleans up tracing output)" ) parser.add_argument('--verbose', '-v', action='count', default=1) parser.add_argument('--quiet', '-q', action='count', default=0) parser.add_argument('--output', '-o', dest="output", default='giltracer.html', help="Output filename (default %(default)s)") parser.add_argument( '--state-detect', help= "Use perf sched events to detect if a process is sleeping due to the GIL (default: %(default)s)", default=False, action='store_true') parser.add_argument('--no-state-detect', dest="state_detect", action='store_false') parser.add_argument( '--gil-detect', help= "Use uprobes to detect who has the GIL (read README.md) (default: %(default)s)", default=True, action='store_true') parser.add_argument('--no-gil-detect', dest="gil_detect", action='store_false') parser.add_argument('args', nargs=argparse.REMAINDER) args = parser.parse_args(argv[1:]) verbose = args.verbose - args.quiet if args.import_: for module in args.import_.split(','): if verbose >= 2: print(f'importing {module}') __import__(module) perf1 = PerfRecordSched(verbose=verbose) if args.state_detect else None perf2 = PerfRecordGIL(verbose=verbose) if args.gil_detect else None vt = viztracer.VizTracer(output_file="viztracer.json", verbose=verbose) # pass on the rest of the arguments sys.argv = args.args if args.module: module = runpy.run_module(args.module) else: module = runpy.run_path(sys.argv[0]) if perf1: perf1.start() if perf2: perf2.start() try: vt.start() module['main'](args.args) finally: vt.stop() if perf1: perf1.stop() if perf2: perf2.stop() vt.save('viztracer.json') if perf1: perf1.post_process() if perf2: perf2.post_process() files = ['viztracer.json'] if perf1: files.append('schedtracer.json') if perf2: files.append('giltracer.json') builder = ReportBuilder(files, verbose=verbose) builder.save(output_file=args.output)