diff options
author | vandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-14 16:37:49 +0000 |
---|---|---|
committer | vandebo@chromium.org <vandebo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-14 16:37:49 +0000 |
commit | 7a4cdac40d2cd8be44ea842a5240ffbb6665eadd (patch) | |
tree | ab9ac9125a0944aadf38cc675c6a003ec41ea469 /tools/net | |
parent | 76e4294ef20fb55b5509dfb12526c047ca0205bb (diff) | |
download | chromium_src-7a4cdac40d2cd8be44ea842a5240ffbb6665eadd.zip chromium_src-7a4cdac40d2cd8be44ea842a5240ffbb6665eadd.tar.gz chromium_src-7a4cdac40d2cd8be44ea842a5240ffbb6665eadd.tar.bz2 |
Add netlog parse/plot script.
BUG=NONE
TEST=NONE
Review URL: http://codereview.chromium.org/3674007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62563 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/net')
-rwxr-xr-x | tools/net/netlog.py | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/tools/net/netlog.py b/tools/net/netlog.py new file mode 100755 index 0000000..610052b --- /dev/null +++ b/tools/net/netlog.py @@ -0,0 +1,177 @@ +#!/usr/bin/python +# Copyright (c) 2010 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Parse NetLog output and reformat it to display in Gnuplot.""" + +import math +import optparse +import os +import re +import sys + + +class Entry(object): + """A single NetLog line/entry.""" + + def __init__(self, line): + self.id = -1 + self.info = '' + self.time = 0 + + time_offset = line.find('t=') + if time_offset >= 0: + tmp = line[time_offset + 2:].split(None, 1) + self.time = tmp[0][:-3] + '.' + tmp[0][-3:] + if len(tmp) > 1: + self.info = tmp[1] + else: + self.info = line + self.info = re.sub('\[dt=[0-9 ?]*\]', '', self.info) + self.info = self.info.strip() + + +class Object(object): + """A set of Entries that belong to the same NetLog Object.""" + + def __init__(self, line, id_offset): + self.id = line[id_offset + 4:].rstrip(')') + self.type = line.split(None, 1)[0] + self.entries = [] + + def SpaceOutEntries(self): + self.__FindGroups(self.__SpaceRange) + + def SetRotation(self): + self.__FindGroups(self.__SetRotationRange) + + def __FindGroups(self, proc): + first = 0 + for i in range(len(self.entries)): + if self.entries[first].time != self.entries[i].time: + proc(first, i - 1) + first = i + proc(first, len(self.entries) - 1) + + def __SpaceRange(self, start, end): + if end > start: + gap = math.floor(100/(end - start + 2)) + for i in range(start + 1, end + 1): + self.entries[i].time += '%02d'%(gap * (i - start)) + + def __SetRotationRange(self, start, end): + for i in range(start, end + 1): + self.entries[i].rotation = 85 - (i - start) * 15 + + +def Parse(stream): + """Parse the NetLog into python objects.""" + + result = [] + request_section = 0 + obj = None + entry = None + + for line in stream: + line = line.strip() + if line.startswith('Requests'): + request_section = 1 + elif line.startswith('Http cache'): + request_section = 0 + + if request_section: + id_offset = line.find('(id=') + if id_offset >= 0: + obj = Object(line, id_offset) + result.append(obj) + elif line.startswith('(P) t=') or line.startswith('t='): + entry = Entry(line) + obj.entries.append(entry) + elif line.find('source_dependency') >= 0: + new_entry = Entry(line) + new_entry.time = entry.time + new_entry.id = line.split(':')[1].split(',')[0] + obj.entries.append(new_entry) + new_entry = Entry('t=%s '%entry.time.replace('.', '')) + obj.entries.append(new_entry) + elif line.startswith('-->'): + entry.info = entry.info + ' ' + line[4:] + + return result + + +def GnuplotRenderNetlog(netlog, filename, labels): + """Render a list of NetLog objects into Gnuplot format.""" + + output = open(filename, 'w') + + commands = [] + data = [] + types = [] + + commands.append('file="%s"'%filename) + commands.append('set key bottom') + commands.append('set xdata time') + commands.append('set timefmt "%s"') + commands.append('set datafile separator ","') + commands.append('set xlabel "Time (s)"') + commands.append('set ylabel "Netlog ID"') + + plot = [] + index = 1 + for obj in netlog: + if obj.type not in types: + types.append(obj.type) + type_num = types.index(obj.type) + plot.append('file index %d using 1:2 with linespoints lt %d notitle'%( + index, type_num)) + obj.SetRotation() + for entry in obj.entries: + graph_id = obj.id + if entry.id > 0: + graph_id = entry.id + data.append('%s,%s'%(entry.time, graph_id)) + info = entry.info.replace('"', '') + if info and labels: + commands.append('set label "%s" at "%s", %s rotate by %d'%( + info, entry.time, obj.id, entry.rotation)) + data.append('\n') + index += 1 + + for entry_type in types: + plot.insert(0, '1/0 lt %d title "%s"'%(types.index(entry_type), entry_type)) + commands.append('plot ' + ','.join(plot)) + commands.append('exit') + result = '\n'.join(commands) + '\n\n\n' + '\n'.join(data) + + output.write(result) + output.close() + os.system('gnuplot %s -'%filename) + + +def main(_): + parser = optparse.OptionParser('usage: %prog [options] dump_file') + parser.add_option_group( + optparse.OptionGroup(parser, 'Additional Info', + 'When run, the script will generate a file that can ' + 'be passed to gnuplot, but will also start gnuplot ' + 'for you; left click selects a zoom region, u ' + 'unzooms, middle click adds a marker, and q quits.')) + parser.add_option('-o', '--output', dest='output', help='Output filename') + parser.add_option('-l', '--labels', action='store_true', help='Output labels') + options, args = parser.parse_args() + if not args: + parser.error('Must specify input dump_file.') + if not options.output: + options.output = args[0] + '.gnuplot' + + netlog = Parse(open(args[0])) + GnuplotRenderNetlog(netlog, options.output, options.labels) + return 0 + + +if '__main__' == __name__: + ret = main(sys.argv) + sys.exit(ret) + |