Example #1
0
    def finish(self):
        GraphCombiner.finish(self)
        cluster_index = 0
        clusters = {}
        for domain, data in self.per_domain.items():
            cluster = clusters.setdefault(cluster_index, [])
            cluster.append('subgraph cluster_%d {\nlabel = "%s";' %
                           (cluster_index, domain))
            # counters
            for counter_name, counter_data in data['counters'].items():
                id = self.make_id(domain, counter_name)
                self._write(
                    '%s [label="{COUNTER: %s|min=%s|max=%s|avg=%s}"];\n' %
                    (id, html.escape(counter_name),
                     format_time(
                         min(counter_data)), format_time(max(counter_data)),
                     format_time(sum(counter_data) / len(counter_data))))
                cluster.append("%s;" % (id))
            # tasks
            for task_name, task_data in data['tasks'].items():
                id = self.make_id(domain, task_name)
                time = task_data['time']
                self._write(
                    '%s [label="{TASK: %s|min=%s|max=%s|avg=%s|count=%d%s}"];\n'
                    % (id, html.escape(task_name), format_time(
                        min(time)), format_time(max(time)),
                       format_time(sum(time) / len(time)), len(time),
                       (("|%s" % task_data['src'].replace('\\', '/'))
                        if 'src' in task_data else "")))
                cluster.append("%s;" % id)
            #: {}, 'objects':{}, 'frames': {}, 'markers': {}
            cluster_index += 1
        # threads
        thread_names = self.tree['threads']
        for tid in self.threads:
            tid_str, tid_hex = str(tid), (to_hex(tid)
                                          if tid is not None else "None")
            id = self.make_id("threads", tid_str)
            thread_name = thread_names[
                tid_str] if tid_str in thread_names else ""
            self._write(
                '%s [label="{THREAD: %s|%s}" color=gray fontcolor=gray];\n' %
                (id, tid_hex, html.escape(thread_name)))

        # clusters
        for _, cluster in clusters.items():
            for line in cluster:
                self._write(line + "\n")
            self._write("}\n")
        # relations
        for relation in self.relations.values():
            if 'color' not in relation:
                relation['color'] = 'black'
            self._write(
                'edge [label="{label}" color={color} fontcolor={color}];\n{from}->{to};\n'
                .format(**relation))

        self._write("}\n")
        self.file.close()
Example #2
0
    def complete_task(self, type, begin, end):
        if 'tid' not in begin:
            return

        start_time = round(begin['time'] /
                           1000)  # sad but it's limiter to milliseconds only
        end_time = round(end['time'] / 1000)
        dur = end_time - start_time
        if dur < self.args.min_dur:
            return

        name = get_name(begin)

        details = (type + ":") if type != 'task' else ""
        if begin.has_key('parent'):
            details += to_hex(begin['parent']) + "->"
        details += name

        if type == 'counter' or type == 'marker':
            kind = 'Painting'
        elif type == 'frame' or 'object_' in type:
            kind = 'Creating'
        else:
            kind = 'Javascript'

        record = (begin['__file__'].replace("\\", "/")
                  if begin.has_key('__file__') else "",
                  begin['__line__'] if begin.has_key('__line__') else "0",
                  kind, "%s | %s" % (details, begin['domain']), name)
        record = tuple([cgi.escape(item) for item in record])

        if self.event_map.has_key(record):
            index = self.event_map[record]
        else:
            index = len(self.events)
            self.events.append(record)
            self.event_map[record] = index

        tag = '<range startTime="%d" duration="%d" eventIndex="%d"/>\n' % (
            start_time, dur, index)

        args = {}
        if type == "counter":
            if 'delta' in begin:
                args['value'] = begin['delta']
            else:  # TODO: add multi-value support
                return
        if begin.has_key('args'):
            args = begin['args']
            if end.has_key('args'):
                args.update(end['args'])
        if args:
            self.notes.append((start_time, dur, index, args))

        self.set_times(start_time, end_time)
        self.file.write(tag)
Example #3
0
    def complete_task(self, type, begin, end):
        if 'tid' not in begin:
            return

        start_time = round(begin['time'] / 1000)  # sad but it's limiter to milliseconds only
        end_time = round(end['time'] / 1000)
        dur = end_time - start_time
        if dur < self.args.min_dur:
            return

        name = get_name(begin)

        details = (type + ":") if type != 'task' else ""
        if begin.has_key('parent'):
            details += to_hex(begin['parent']) + "->"
        details += name

        if type == 'counter' or type == 'marker':
            kind = 'Painting'
        elif type == 'frame' or 'object_' in type:
            kind = 'Creating'
        else:
            kind = 'Javascript'

        record = (
            begin['__file__'].replace("\\", "/") if begin.has_key('__file__') else "",
            begin['__line__'] if begin.has_key('__line__') else "0",
            kind,
            "%s | %s" % (details, begin['domain']),
            name
        )
        record = tuple([cgi.escape(item) for item in record])

        if self.event_map.has_key(record):
            index = self.event_map[record]
        else:
            index = len(self.events)
            self.events.append(record)
            self.event_map[record] = index

        tag = '<range startTime="%d" duration="%d" eventIndex="%d"/>\n' % (start_time, dur, index)

        args = {}
        if type == "counter":
            args['value'] = begin['delta']
        if begin.has_key('args'):
            args = begin['args']
            if end.has_key('args'):
                args.update(end['args'])
        if args:
            self.notes.append((start_time, dur, index, args))

        self.set_times(start_time, end_time)
        self.file.write(tag)
Example #4
0
    def finish(self):
        self.file.write('<Nodes>\n')
        for domain, data in self.per_domain.iteritems():
            # counters
            for counter_name, counter_data in data['counters'].iteritems():
                id = self.make_id(domain, counter_name)
                self.file.write('<Node Id="%s" Label="%s" Min="%g" Max="%g" Avg="%g" Category="CodeSchema_Type"/>\n' % (id, cgi.escape(counter_name), min(counter_data), max(counter_data), sum(counter_data) / len(counter_data)))
            # tasks
            for task_name, task_data in data['tasks'].iteritems():
                id = self.make_id(domain, task_name)
                time = task_data['time']
                self.file.write('<Node Id="%s" Category="CodeSchema_Method" Label="%s" Min="%s" Max="%s" Avg="%s" Count="%d" Src="%s"/>\n' % (
                        id, cgi.escape(task_name),
                        format_time(min(time)), format_time(max(time)), format_time(sum(time) / len(time)), len(time),
                        task_data['src'].replace('\\', '/') if task_data.has_key('src') else ""
                    )
                )
            self.file.write('<Node Id="%s" Label="%s" Category="CodeSchema_Namespace" Group="Expanded"/>\n' % (self.make_id("domain", domain), cgi.escape(domain)))
        # threads
        thread_names = self.tree['threads']
        for tid in self.threads:
            tid_str, tid_hex = str(tid), (to_hex(tid) if tid is not None else "None")
            id = self.make_id("threads", tid_str)
            thread_name = thread_names[tid_str] if thread_names.has_key(tid_str) else ""
            self.file.write('<Node Id="%s" Label="%s(%s)"/>\n' % (id, cgi.escape(thread_name), tid_hex))

        self.file.write('</Nodes>\n')
        self.file.write('<Links>\n')

        # relations
        for relation in self.relations.itervalues():
            if not relation.has_key('color'):
                relation['color'] = 'black'
            self.file.write('<Link Source="{from}" Target="{to}" Category="CodeSchema_Calls"/>\n'.format(**relation))

        for domain, data in self.per_domain.iteritems():
            # counters
            for counter_name, counter_data in data['counters'].iteritems():
                self.file.write('<Link Source="%s" Target="%s" Category="Contains"/>\n' % (self.make_id("domain", domain), self.make_id(domain, counter_name)))
            # tasks
            for task_name, task_data in data['tasks'].iteritems():
                self.file.write('<Link Source="%s" Target="%s" Category="Contains"/>\n' % (self.make_id("domain", domain), self.make_id(domain, task_name)))

        self.file.write('</Links>\n')

        self.file.write("</DirectedGraph>\n")
        self.file.close()
Example #5
0
    def finish(self):
        self.file.write('<Nodes>\n')
        for domain, data in self.per_domain.iteritems():
            # counters
            for counter_name, counter_data in data['counters'].iteritems():
                id = self.make_id(domain, counter_name)
                self.file.write('<Node Id="%s" Label="%s" Min="%g" Max="%g" Avg="%g" Category="CodeSchema_Type"/>\n' % (id, cgi.escape(counter_name), min(counter_data), max(counter_data), sum(counter_data) / len(counter_data)))
            # tasks
            for task_name, task_data in data['tasks'].iteritems():
                id = self.make_id(domain, task_name)
                time = task_data['time']
                self.file.write('<Node Id="%s" Category="CodeSchema_Method" Label="%s" Min="%s" Max="%s" Avg="%s" Count="%d" Src="%s"/>\n' % (
                        id, cgi.escape(task_name),
                        format_time(min(time)), format_time(max(time)), format_time(sum(time) / len(time)), len(time),
                        task_data['src'].replace('\\', '/') if task_data.has_key('src') else ""
                    )
                )
            self.file.write('<Node Id="%s" Label="%s" Category="CodeSchema_Namespace" Group="Expanded"/>\n' % (self.make_id("domain", domain), cgi.escape(domain)))
        # threads
        thread_names = self.tree['threads']
        for tid in self.threads:
            tid_str, tid_hex = str(tid), to_hex(tid)
            id = self.make_id("threads", tid_str)
            thread_name = thread_names[tid_str] if thread_names.has_key(tid_str) else ""
            self.file.write('<Node Id="%s" Label="%s(%s)"/>\n' % (id, cgi.escape(thread_name), tid_hex))

        self.file.write('</Nodes>\n')
        self.file.write('<Links>\n')

        # relations
        for relation in self.relations.itervalues():
            if not relation.has_key('color'):
                relation['color'] = 'black'
            self.file.write('<Link Source="{from}" Target="{to}" Category="CodeSchema_Calls"/>\n'.format(**relation))

        for domain, data in self.per_domain.iteritems():
            # counters
            for counter_name, counter_data in data['counters'].iteritems():
                self.file.write('<Link Source="%s" Target="%s" Category="Contains"/>\n' % (self.make_id("domain", domain), self.make_id(domain, counter_name)))
            # tasks
            for task_name, task_data in data['tasks'].iteritems():
                self.file.write('<Link Source="%s" Target="%s" Category="Contains"/>\n' % (self.make_id("domain", domain), self.make_id(domain, task_name)))

        self.file.write('</Links>\n')

        self.file.write("</DirectedGraph>\n")
        self.file.close()
Example #6
0
    def finish(self):
        cluster_index = 0
        clusters = {}
        for domain, data in self.per_domain.iteritems():
            cluster = clusters.setdefault(cluster_index, [])
            cluster.append('subgraph cluster_%d {\nlabel = "%s";' % (cluster_index, domain))
            # counters
            for counter_name, counter_data in data['counters'].iteritems():
                id = self.make_id(domain, counter_name)
                self.file.write('%s [label="{COUNTER: %s|min=%g|max=%g|avg=%g}"];\n' % (id, cgi.escape(counter_name), min(counter_data), max(counter_data), sum(counter_data) / len(counter_data)))
                cluster.append("%s;" % (id))
            # tasks
            for task_name, task_data in data['tasks'].iteritems():
                id = self.make_id(domain, task_name)
                time = task_data['time']
                self.file.write(
                    '%s [label="{TASK: %s|min=%s|max=%s|avg=%s|count=%d%s}"];\n' % (
                        id,
                        cgi.escape(task_name), format_time(min(time)), format_time(max(time)), format_time(sum(time) / len(time)), len(time),
                        (("|%s" % task_data['src'].replace('\\', '/')) if task_data.has_key('src') else "")
                    )
                )
                cluster.append("%s;" % id)
            #: {}, 'objects':{}, 'frames': {}, 'markers': {}
            cluster_index += 1
        # threads
        thread_names = self.tree['threads']
        for tid in self.threads:
            tid_str, tid_hex = str(tid), (to_hex(tid) if tid is not None else "None")
            id = self.make_id("threads", tid_str)
            thread_name = thread_names[tid_str] if thread_names.has_key(tid_str) else ""
            self.file.write('%s [label="{THREAD: %s|%s}" color=gray fontcolor=gray];\n' % (id, tid_hex, cgi.escape(thread_name)))

        # clusters
        for _, cluster in clusters.iteritems():
            for line in cluster:
                self.file.write(line + "\n")
            self.file.write("}\n")
        # relations
        for relation in self.relations.itervalues():
            if not relation.has_key('color'):
                relation['color'] = 'black'
            self.file.write('edge [label="{label}" color={color} fontcolor={color}];\n{from}->{to};\n'.format(**relation))

        self.file.write("}\n")
        self.file.close()
Example #7
0
    def format_task(self, phase, type, begin, end):
        res = []
        res.append('{"ph":"%s"' % phase)
        res.append(', "pid":%(pid)d' % begin)
        if begin.has_key('tid'):
            res.append(', "tid":%(tid)d' % begin)
        if GT_FLOAT_TIME:
            res.append(', "ts":%.3f' % (self.convert_time(begin['time'])))
        else:
            res.append(', "ts":%d' % (self.convert_time(begin['time'])))
        if "counter" == type:  # workaround of chrome issue with forgetting the last counter value
            self.counters.setdefault(begin['domain'], {})[begin['str']] = begin  # remember the last counter value
        if "marker" == type:
            name = begin['str']
            res.append(', "s":"%s"' % (GoogleTrace.Markers[begin['data']]))
        elif "object_" in type:
            if 'str' in begin:
                name = begin['str']
            else:
                name = ""
        elif "frame" == type:
            if 'str' in begin:
                name = begin['str']
            else:
                name = begin['domain']
        else:
            if type not in ["counter", "task", "overlapped"]:
                name = type + ":"
            else:
                name = ""

            if 'parent' in begin:
                name += to_hex(begin['parent']) + "->"
            if 'str' in begin:
                name += begin['str'] + ":"
            if 'pointer' in begin:
                name += "func<" + to_hex(begin['pointer']) + ">:"
            else:
                name = name.rstrip(":")

        assert (name or "object_" in type)
        res.append(', "name":"%s"' % name)
        res.append(', "cat":"%s"' % (begin['domain']))

        if 'id' in begin:
            res.append(', "id":"%s"' % str(begin['id']))
        if type in ['task']:
            dur = self.convert_time(end['time']) - self.convert_time(begin['time'])
            if dur < self.args.min_dur:
                return []
            if GT_FLOAT_TIME:
                res.append(', "dur":%.3f' % dur)
            else:
                res.append(', "dur":%d' % dur)
        args = {}
        if 'args' in begin:
            args = begin['args'].copy()
        if 'args' in end:
            args.update(end['args'])
        if '__file__' in begin:
            args["__file__"] = begin["__file__"]
            args["__line__"] = begin["__line__"]
        if 'counter' == type:
            if 'delta' in begin:  # multi-counter is passed as named sub-counters dict
                args[name] = begin['delta']
        if 'memory' in begin:
            total = 0
            breakdown = {}
            children = 0
            for size, values in begin['memory'].iteritems():
                if size is None:  # special case for children attribution
                    children = values
                else:
                    all = sum(values)
                    total += size * all
                    if all:
                        breakdown[size] = all
            breakdown['TOTAL'] = total
            breakdown['CHILDREN'] = children
            args['CRT:Memory(size,count)'] = breakdown
        if args:
            res.append(', "args":')
            res.append(self.format_value(args))
        res.append('}')
        return res
Example #8
0
    def format_task(self, phase, type, begin, end):
        res = []
        res.append('{"ph":"%s"' % (phase))
        res.append(', "pid":%(pid)d' % begin)
        if begin.has_key('tid'):
            res.append(', "tid":%(tid)d' % begin)
        if GT_FLOAT_TIME:
            res.append(', "ts":%.3f' % (self.convert_time(begin['time'])))
        else:
            res.append(', "ts":%d' % (self.convert_time(begin['time'])))
        if "counter" == type:  # workaround of chrome issue with forgetting the last counter value
            self.counters.setdefault(begin['domain'], {})[begin['str']] = begin  # remember the last counter value
        if "marker" == type:
            name = begin['str']
            res.append(', "s":"%s"' % (GoogleTrace.Markers[begin['data']]))
        elif "object_" in type:
            if begin.has_key('str'):
                name = begin['str']
            else:
                name = ""
        elif "frame" == type:
            if begin.has_key('str'):
                name = begin['str']
            else:
                name = begin['domain']
        else:
            if type not in ["counter", "task", "overlapped"]:
                name = type + ":"
            else:
                name = ""

            if begin.has_key('parent'):
                name += to_hex(begin['parent']) + "->"
            if begin.has_key('str'):
                name += begin['str'] + ":"
            if begin.has_key('pointer'):
                name += "func<" + to_hex(begin['pointer']) + ">:"
            if begin.has_key('id') and type != "overlapped":
                name += "(" + to_hex(begin['id']) + ")"
            else:
                name = name.rstrip(":")

        assert (name or "object_" in type)
        res.append(', "name":"%s"' % (name))
        res.append(', "cat":"%s"' % (begin['domain']))

        if begin.has_key('id'):
            res.append(', "id":%s' % (begin['id']))
        if type in ['task']:
            dur = self.convert_time(end['time']) - self.convert_time(begin['time'])
            if GT_FLOAT_TIME:
                res.append(', "dur":%.3f' % (dur))
            else:
                if dur < self.args.min_dur:
                    return []  # google misbehaves on tasks of 0 length
                res.append(', "dur":%d' % (dur))
        args = {}
        if begin.has_key('args'):
            args = begin['args'].copy()
        if end.has_key('args'):
            args.update(end['args'])
        if begin.has_key('__file__'):
            args["__file__"] = begin["__file__"]
            args["__line__"] = begin["__line__"]
        if 'counter' == type:
            args[name] = begin['delta']
        if begin.has_key('memory'):
            total = 0
            breakdown = {}
            children = 0
            for size, values in begin['memory'].iteritems():
                if size is None:  # special case for children attribution
                    children = values
                else:
                    all = sum(values)
                    total += size * all
                    if all:
                        breakdown[size] = all
            breakdown['TOTAL'] = total
            breakdown['CHILDREN'] = children
            args['CRT:Memory(size,count)'] = breakdown
        if args:
            res.append(', "args":')
            res.append(self.format_value(args))
        res.append('}');
        return res