Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Unified Diff: net/tools/dns_trace_formatter/formatter.py

Issue 2008007: Replace about:net-internals with the javascript-based frontend.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: improve a comment Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/net.gyp ('k') | net/tools/dns_trace_formatter/parser.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/tools/dns_trace_formatter/formatter.py
===================================================================
--- net/tools/dns_trace_formatter/formatter.py (revision 46824)
+++ net/tools/dns_trace_formatter/formatter.py (working copy)
@@ -1,310 +0,0 @@
-#!/usr/bin/python2.4
-# 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.
-
-"""Application to format Chromium's host resolver traces to something readable.
-
-To use it, start by enabling tracing in Chromium:
- chrome://net-internals/hostresolver
-
-Next, copy-paste the trace results (those lines starting with "t=") and save
-them to a text file.
-
-Lastly, run:
- python formatter.py <file-containing-trace>
-"""
-
-import sys
-
-import parser
-
-# The log lines of the host resolver trace either describe a "request" or a
-# "job". The "request" is the actual DNS resolve request, whereas the "job" is
-# a helper that was spawned to service requests on a particular thread.
-#
-# In the log lines, each request or job is identified using a unique numeric ID.
-#
-# Since DNS resolving is multi-threaded, the log lines may appear jumbled.
-#
-# The first thing this code does is to group the log lines by id. This
-# collection of log lines is called an "entry", and represented by either
-# RequestEntry or JobEntry.
-#
-# So for example, say we had a log resembling:
-#
-# t=1: starting request r1
-# t=1: starting job j1
-# t=2: starting request r2
-# t=3: completed job j1
-# t=4: finished request r2
-# t=5: cancelled request r1
-#
-# We would start by building three entries:
-#
-# (id='r1')
-# t=1: starting request r1
-# t=5: cancelled request r1
-#
-# (id='j1')
-# t=1: starting job j1
-# t=3: completed job j1
-#
-# (id='r2')
-# t=2: starting request r2
-# t=4: finished request r2
-
-(ENTRY_TYPE_JOB, ENTRY_TYPE_REQUEST) = (0, 1)
-
-
-class EntryBase(object):
- """Helper structure that describes an individual hostresolver request/job."""
-
- def __init__(self, entries, entity_id, parsed_lines):
- """Constructor for EntryBase.
-
- Args:
- entries: The full list of EntryBase that this new instance belongs to.
- entity_id: The ID of this request/job.
- parsed_lines: An ordered list of ParsedLine for the log lines that apply
- to this request/job.
- """
- self._entries = entries
- self._entity_id = entity_id
- self._parsed_lines = parsed_lines
-
- def HasParsedLineOfType(self, line_type):
- """Returns true if this request/job contains a log line of type |type|."""
- for line in self._parsed_lines:
- if line.line_type == line_type:
- return True
- return False
-
- def GetElapsedTime(self):
- """Returns the start to finish duration of this request/job."""
- return self.GetEndTime() - self.GetStartTime()
-
- def GetStartTime(self):
- """Returns the start time for this request/job."""
- return self._parsed_lines[0].t
-
- def GetEndTime(self):
- """Returns the end time of this request/job."""
- return self._parsed_lines[-1].t
-
- def HasUnknownStart(self):
- """Returns true if the exact start of this request/job is unknown."""
- return 'is_fake' in self._parsed_lines[0].details
-
- def HasUnknownEnd(self):
- """Returns true if the exact end of this request/job is unknown."""
- return 'is_fake' in self._parsed_lines[-1].details
-
- def WasAliveAt(self, t):
- """Returns true if this request/job was running at time |t|."""
- return t >= self.GetStartTime() and t <= self.GetEndTime()
-
- def GetEntryType(self):
- """Returns whether this entry represents a request or a job.
- Should be one of the enums ENTRY_TYPE_*"""
- return None
-
- def GetLiveEntriesAtStart(self, entry_type):
- return [entry for entry in self._entries
- if (entry != self and entry.WasAliveAt(self.GetStartTime()) and
- entry.GetEntryType() == entry_type)]
-
- def Print(self):
- """Outputs a text description of this request/job."""
- print '------------------------'
- print self.GetCaption()
- print '------------------------'
- print self.GetDetails()
-
- def GetElapsedTimeString(self):
- """Returns a string that describes how long this request/job took."""
- if self.HasUnknownStart() or self.HasUnknownEnd():
- return '%d+ millis' % self.GetElapsedTime()
- return '%d millis' % self.GetElapsedTime()
-
-
-class RequestEntry(EntryBase):
- """Specialization of EntryBase that describes hostresolver request."""
-
- def __init__(self, entries, entity_id, parsed_lines, min_time, max_time):
- """Constructor for RequestEntry.
-
- Args:
- entries: The full list of EntryBase that this new instance belongs to.
- entity_id: The ID of this request.
- parsed_lines: An ordered list of ParsedLine for the log lines that apply
- to this request.
- min_time: The start time of the log.
- max_time: The end time of the log.
- """
- EntryBase.__init__(self, entries, entity_id, parsed_lines)
-
- # Scan the parsed lines for this request to find the details on the request.
- self.request_details = '???'
- for line in parsed_lines:
- if 'request_details' in line.details:
- self.request_details = line.details['request_details']
- break
-
- # If the log didn't capture when the request was received, manufacture a log
- # entry for the start, at t = min_time - 1
- if not self.HasParsedLineOfType(parser.LINE_TYPE_RECEIVED_REQUEST):
- fake_line = parser.ParsedLine()
- fake_line.t = min_time - 1
- fake_line.line_type = parser.LINE_TYPE_RECEIVED_REQUEST
- fake_line.raw_line = 'Unknown start of request'
- fake_line.details['is_fake'] = True
- self._parsed_lines.insert(0, fake_line)
-
- # If the log didn't capture when the job ended, manufacture a log entry for
- # the end, at t = max_time + 1
- if not (self.HasParsedLineOfType(parser.LINE_TYPE_FINISHED_REQUEST) or
- self.HasParsedLineOfType(parser.LINE_TYPE_CANCELLED_REQUEST)):
- fake_line = parser.ParsedLine()
- fake_line.t = max_time + 1
- fake_line.line_type = parser.LINE_TYPE_FINISHED_REQUEST
- fake_line.raw_line = 'Unknown end of request'
- fake_line.details['is_fake'] = True
- self._parsed_lines.append(fake_line)
-
- def GetEntryType(self):
- return ENTRY_TYPE_REQUEST
-
- def GetCaption(self):
- return 'Request %s (took %s) for %s ' % (self._entity_id,
- self.GetElapsedTimeString(),
- self.request_details)
-
- def GetDetails(self):
- reqs = self.GetLiveEntriesAtStart(ENTRY_TYPE_REQUEST)
- out = [('There were %d requests already in progress when this '
- 'started:') % len(reqs)]
- out.extend([' ' + r.GetCaption() for r in reqs])
-
- out.append('Log lines:')
- out.extend([' ' + line.raw_line for line in self._parsed_lines])
-
- return '\n'.join(out)
-
-
-class JobEntry(EntryBase):
- """Specialization of EntryBase that describes hostresolver request."""
-
- def __init__(self, entries, entity_id, parsed_lines, min_time, max_time):
- """Constructor for JobEntry.
-
- Args:
- entries: The full list of EntryBase that this new instance belongs to.
- entity_id: The ID of this job.
- parsed_lines: An ordered list of ParsedLine for the log lines that apply
- to this job.
- min_time: The start time of the log.
- max_time: The end time of the log.
- """
- EntryBase.__init__(self, entries, entity_id, parsed_lines)
-
- # Find the hostname/address_family of the job
- self.hostname = '???'
- self.address_family = '???'
-
- for line in parsed_lines:
- if 'hostname' in line.details and 'address_family' in line.details:
- self.hostname = line.details['hostname']
- self.address_family = line.details['address_family']
- break
-
- # If the log didn't capture when the job started, manufacture a start time.
- if not (self.HasParsedLineOfType(parser.LINE_TYPE_CREATED_JOB) or
- self.HasParsedLineOfType(parser.LINE_TYPE_OUTSTANDING_JOB) or
- self.HasParsedLineOfType(parser.LINE_TYPE_STARTING_JOB)):
- fake_line = parser.ParsedLine()
- fake_line.t = min_time - 1
- fake_line.line_type = parser.LINE_TYPE_OUTSTANDING_JOB
- fake_line.raw_line = 'Unknown start of job'
- fake_line.details['is_fake'] = True
- self._parsed_lines.insert(0, fake_line)
-
- # If the log didn't capture when the job ended, manufacture an end time.
- if not self.HasParsedLineOfType(parser.LINE_TYPE_COMPLETING_JOB):
- fake_line = parser.ParsedLine()
- fake_line.t = max_time + 1
- fake_line.line_type = parser.LINE_TYPE_COMPLETING_JOB
- fake_line.raw_line = 'Unknown end of job'
- fake_line.details['is_fake'] = True
- self._parsed_lines.append(fake_line)
-
- def GetEntryType(self):
- return ENTRY_TYPE_JOB
-
- def GetCaption(self):
- return 'Job %s (took %s) for "%s" ' % (self._entity_id,
- self.GetElapsedTimeString(),
- self.hostname)
-
- def GetDetails(self):
- jobs = self.GetLiveEntriesAtStart(ENTRY_TYPE_JOB)
- out = [('There were %d jobs already in progress when '
- 'this started:' % len(jobs))]
- out.extend([' ' + j.GetCaption() for j in jobs])
-
- out.append('Log lines:')
- out.extend([' ' + line.raw_line for line in self._parsed_lines])
-
- return '\n'.join(out)
-
-
-def BuildEntries(parsed_lines, min_time, max_time):
- """Returns a list of BaseEntrys built from |parsed_lines|."""
-
- # In this loop we aggregate all of the parsed lines with common entity_id, and
- # also determine the order that entity_ids are first seen in.
- id_to_line_list = {}
- entity_ids = []
- for line in parsed_lines:
- entity_id = line.entity_id
- if not entity_id in entity_ids:
- entity_ids.append(entity_id)
- lines = id_to_line_list.setdefault(entity_id, [])
- lines.append(line)
-
- # Create an entry (either JobEntry or RequestEntry) for each unique entity_id
- # in the trace. Ordered by their first appearance in the trace.
-
- entries = []
- for entity_id in entity_ids:
- if entity_id.startswith('j'):
- entries.append(JobEntry(entries,
- entity_id, id_to_line_list[entity_id],
- min_time, max_time))
- if entity_id.startswith('r'):
- entries.append(RequestEntry(entries,
- entity_id, id_to_line_list[entity_id],
- min_time, max_time))
-
- return entries
-
-
-def main():
- if len(sys.argv) != 2:
- print 'Usage: %s <logfile_path>' % sys.argv[0]
- sys.exit(1)
-
- parsed_lines = parser.ParseFile(sys.argv[1])
-
- min_time = parsed_lines[0].t
- max_time = parsed_lines[-1].t
-
- entries = BuildEntries(parsed_lines, min_time, max_time)
-
- for entry in entries:
- entry.Print()
-
-
-if __name__ == '__main__':
- main()
-
« no previous file with comments | « net/net.gyp ('k') | net/tools/dns_trace_formatter/parser.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698