Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
    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()
Ejemplo n.º 3
0
    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")
Ejemplo n.º 4
0
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])
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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()
Ejemplo n.º 8
0
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)