Beispiel #1
0
    def _tree_handler(self, environ, start_response):
        params = _parse_params(environ)
        node_thres = float(params.get('node_thres', 0.5))
        edge_thres = float(params.get('edge_thres', 0.1))
        results = self._get_results_by_request(params)
        if not results:
            start_response('200 OK', [('Content-Type', 'text/plain')])
            return [b'No matching log.']

        # pstats.Stats() hits recursion limit when many profiles are passed.
        parser = gprof2dot.PstatsParser(results[0])
        for result in results[1:]:
            parser.stats.add(result)
        parsed_profile = parser.parse()
        parsed_profile.prune(node_thres / 100.0, edge_thres / 100.0)

        output = io.StringIO() if six.PY3 else io.BytesIO()
        writer = gprof2dot.DotWriter(output)
        writer.graph(parsed_profile, gprof2dot.TEMPERATURE_COLORMAP)
        dot_data = output.getvalue()
        if six.PY3:
            dot_data = dot_data.encode('utf-8')

        try:
            proc = subprocess.Popen(
                ['dot', '-Tpng'],
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE)
            png_data, _ = proc.communicate(dot_data)
        except Exception:
            start_response('200 OK', [('Content-Type', 'text/plain')])
            return [b'ERROR: Failed to execute "dot". Please install graphviz.']
        else:
            start_response('200 OK', [('Content-Type', 'image/png')])
            return [png_data]
Beispiel #2
0
    def save_data(self):
        try:
            import gprof2dot
            import pyprof2calltree
        except ImportError:
            msg = ('Unable to start profiling.\n Please either '
                   'disable performance profiling in settings.yaml or '
                   'install all modules listed in test-requirements.txt.')
            raise error.ProfilingError(msg)

        self.profiler.disable()
        elapsed = time.time() - self.start
        pref_filename = os.path.join(
            self.paths['last_performance_test'],
            '{method:s}.{handler_name:s}.{elapsed_time:.0f}ms.{t_time}.'.
            format(method=self.method,
                   handler_name=self.handler_name or 'root',
                   elapsed_time=elapsed * 1000.0,
                   t_time=time.time()))
        tree_file = pref_filename + 'prof'
        stats_file = pref_filename + 'txt'
        callgraph_file = pref_filename + 'dot'

        # write pstats
        with file(stats_file, 'w') as file_o:
            stats = Stats(self.profiler, stream=file_o)
            stats.sort_stats('time', 'cumulative').print_stats()

        # write callgraph in dot format
        parser = gprof2dot.PstatsParser(self.profiler)

        def get_function_name((filename, line, name)):
            module = os.path.splitext(filename)[0]
            module_pieces = module.split(os.path.sep)
            return "{module:s}:{line:d}:{name:s}".format(module="/".join(
                module_pieces[-4:]),
                                                         line=line,
                                                         name=name)

        parser.get_function_name = get_function_name
        gprof = parser.parse()

        with open(callgraph_file, 'w') as file_o:
            dot = gprof2dot.DotWriter(file_o)
            theme = gprof2dot.TEMPERATURE_COLORMAP
            dot.graph(gprof, theme)

        # write calltree
        call_tree = pyprof2calltree.CalltreeConverter(stats)
        with file(tree_file, 'wb') as file_o:
            call_tree.output(file_o)
Beispiel #3
0
    def __rungprof2dot(self):
        """Runs gprof2dot which produces a full dot spec"""
        nodeLimit = Settings().getProfilerSettings().nodeLimit
        edgeLimit = Settings().getProfilerSettings().edgeLimit
        with io.StringIO() as buf:
            gprofParser = gprof2dot.PstatsParser(self.__dataFile)
            profileData = gprofParser.parse()
            profileData.prune(nodeLimit / 100.0, edgeLimit / 100.0, False)

            dot = gprof2dot.DotWriter(buf)
            dot.strip = False
            dot.wrap = False
            dot.graph(profileData, gprof2dot.TEMPERATURE_COLORMAP)

            output = buf.getvalue()
        return self.__postprocessFullDotSpec(output)
Beispiel #4
0
    def _prepare_profile(self):
        """Prepares profiling information."""
        if not self._profile_enabled or not hasattr(self, '_prof'):
            return None

        if not gprof2dot:
            logging.warn('failed to import ``gprof2dot``, will not profile')
            return None

        self._prof.create_stats()
        parser = gprof2dot.PstatsParser(self._prof)

        def get_function_name((filename, line, name)):
            module = os.path.splitext(filename)[0]
            module_pieces = module.split(os.path.sep)
            return "%s:%d:%s" % ("/".join(module_pieces[-4:]), line, name)

        parser.get_function_name = get_function_name
        output = StringIO()
        gprof = parser.parse()

        gprof.prune(0.005, 0.001)
        # TODO: ^--- Parameterize node and edge thresholds.
        dot = gprof2dot.DotWriter(output)
        theme = gprof2dot.TEMPERATURE_COLORMAP
        theme.bgcolor = (0.0, 0.0, 0.0)
        # ^--- Use black text, for less eye-bleeding.
        dot.graph(gprof, theme)

        def get_info(self):
            s = "Profile Graph:"
            s += " %.3fs CPU" % self.total_tt
            s += ": %d function calls" % self.total_calls
            if self.total_calls != self.prim_calls:
                s += " (%d primitive calls)" % self.prim_calls
            return s

        profile = {
            "producer": "gprof2dot",
            "producerVersion": str(gprof2dot.__version__),
            "info": get_info(parser.stats),
            "dot": output.getvalue(),
        }

        return profile
Beispiel #5
0
    def _write_dot_graph(self, name, path, prune=''):
        parser = gprof2dot.PstatsParser(path)
        profile = parser.parse()

        funcId = self._find_func_id_for_test_case(profile, name)
        if funcId:
            profile.prune_root(funcId)

        if prune == self.PRUNED_CUMULATIVE:
            profile.prune(0.005, 0.001, None, True)
        elif prune == self.PRUNED_INTERNAL:
            profile.prune(0.005, 0.001, None, True)
        else:
            profile.prune(0, 0, None, False)

        with open(self._get_test_dot_filename(name, prune), 'wt') as f:
            dot = gprof2dot.DotWriter(f)
            dot.graph(profile, self.TEMPERATURE_COLORMAP)
Beispiel #6
0
    def save_data(self):
        elapsed = time.time() - self.start
        pref_filename = os.path.join(
            settings.LOAD_TESTS_PATHS['last_performance_test'],
            '{method:s}.{handler_name:s}.{elapsed_time:.0f}ms.{t_time}.'.
            format(
                method=self.method,
                handler_name=self.handler_name or 'root',
                elapsed_time=elapsed * 1000.0,
                t_time=time.time()))
        tree_file = pref_filename + 'prof'
        stats_file = pref_filename + 'txt'
        callgraph_file = pref_filename + 'dot'

        # write pstats
        with file(stats_file, 'w') as file_o:
            stats = Stats(self.profiler, stream=file_o)
            stats.sort_stats('time', 'cumulative').print_stats()

        # write callgraph in dot format
        parser = gprof2dot.PstatsParser(self.profiler)

        def get_function_name((filename, line, name)):
            module = os.path.splitext(filename)[0]
            module_pieces = module.split(os.path.sep)
            return "{module:s}:{line:d}:{name:s}".format(
                module="/".join(module_pieces[-4:]),
                line=line,
                name=name)

        parser.get_function_name = get_function_name
        gprof = parser.parse()

        with open(callgraph_file, 'w') as file_o:
            dot = gprof2dot.DotWriter(file_o)
            theme = gprof2dot.TEMPERATURE_COLORMAP
            dot.graph(gprof, theme)

        # write calltree
        call_tree = pyprof2calltree.CalltreeConverter(stats)
        with file(tree_file, 'wb') as file_o:
            call_tree.output(file_o)
        def wrapper(*args, **kwargs):
            # Build the path to the folder where we want to keep the results
            # Make sure this directory exists
            if not os.path.isdir(output_directory):
                os.makedirs(output_directory)

            # Run and profile the function, dumping the resulting stats into a
            # file in the results directory.
            pstats_file = os.path.join(
                output_directory, "%s_pstats_results.pstats" % (f.__name__))

            profiler = cProfile.Profile()
            profiler.runcall(f, *args, **kwargs)
            profiler.dump_stats(pstats_file)

            # Dump the profile stats in a human readable for to a file on
            # disk
            stats_file = os.path.join(
                output_directory, "%s_profiler_results.stats" % (f.__name__))

            # Temporarily redirect stdout to somewhere else
            fd = open(stats_file, "w")

            _stdout = sys.stdout
            sys.stdout = fd

            # Dump the stats to this file
            profiler.print_stats()

            # Point stdout back to what it should be
            sys.stdout = _stdout
            fd.close()

            # Now we want to dump the stats to a pretty graph.
            if graph:

                class FakeOptions(object):
                    """A fake options object to trick the gprof2dot main method."""
                    pass

                # Setup an instance of gprof2dot, forcing some options that
                # would usually come through the command line.
                gprof = gprof2dot.Main()

                gprof.options = FakeOptions()
                gprof.options.node_thres = 0.5
                gprof.options.edge_thres = 0.1
                gprof.options.wrap = False
                gprof.options.strip = False
                gprof.options.theme = "color"

                gprof.theme = gprof2dot.Main.themes[gprof.options.theme]

                # Now build the graph
                parser = gprof2dot.PstatsParser(pstats_file)
                gprof.profile = parser.parse()

                dot_file = os.path.join(output_directory,
                                        "%s_dot_results.dot" % (f.__name__))

                gprof.output = open(dot_file, 'wt')
                gprof.write_graph()
                gprof.output.close()

                dot_graph = pydot.graph_from_dot_file(dot_file)

                png_file = os.path.join(output_directory,
                                        "%s_profiler_graph.png" % (f.__name__))

                dot_graph.write(png_file, format="png", prog="dot")
import pstats
from glob import glob
import gprof2dot
import subprocess
import shlex

direct_ory = 'Results/dhfr-explicit/01-25-2016'
profiles = dict()
for dirname in glob('{}/*'.format(direct_ory), recursive=True):
    prof_file = '{}/benchmark.prof'.format(dirname)
    outputfile = '{}/bench.dot'.format(dirname)
    image = '{}/bench.png'.format(dirname)
    txt = '{}/bench_pstats.txt'.format(dirname)
    ps = pstats.Stats(prof_file, stream=open(txt, 'w'))
    ps.strip_dirs()
    ps.sort_stats('time')

    ps.print_stats()

    profile = gprof2dot.PstatsParser(prof_file).parse()
    profile.prune(0.5 / 100.0, 0.1 / 100.0)

    dot = gprof2dot.DotWriter(open(outputfile, 'wt', encoding='UTF-8'))
    dot.strip = False
    dot.wrap = False
    dot.graph(profile, gprof2dot.themes["color"])