1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
#!/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.
"""Package for parsing the log lines from a Chromium DNS trace capture."""
import re
# The type of log line.
(LINE_TYPE_OUTSTANDING_JOB,
LINE_TYPE_CREATED_JOB,
LINE_TYPE_STARTING_JOB,
LINE_TYPE_RUNNING_JOB,
LINE_TYPE_COMPLETED_JOB,
LINE_TYPE_COMPLETING_JOB,
LINE_TYPE_RECEIVED_REQUEST,
LINE_TYPE_ATTACHED_REQUEST,
LINE_TYPE_FINISHED_REQUEST,
LINE_TYPE_CANCELLED_REQUEST) = range(10)
class ParsedLine(object):
"""Structure that represents a parsed line from the trace log.
Attributes:
t: The time (in milliseconds) when the line was logged.
line_type: The type of event that this line was logging. One of LINE_TYPE_*.
raw_line: The full unparsed line.
details: Dictionary containing additional properties that were parsed from
this line.
"""
def __init__(self):
self.t = None
self.line_type = None
self.raw_line = None
self.details = {}
def ParseLine(line):
"""Parses |line| into a ParsedLine. Returns None on failure."""
m = re.search(r'^t=(\d+): "(.*)"\s*$', line)
if not m:
return None
parsed = ParsedLine()
parsed.t = int(m.group(1))
parsed.raw_line = line.strip()
msg = m.group(2)
m = re.search(r"^Received request (r\d+) for (.*)$", msg)
if m:
parsed.line_type = LINE_TYPE_RECEIVED_REQUEST
parsed.entity_id = m.group(1)
parsed.details['request_details'] = m.group(2)
return parsed
m = re.search(r"^Created job (j\d+) for {hostname='([^']*)', "
"address_family=(\d+)}$", msg)
if m:
parsed.line_type = LINE_TYPE_CREATED_JOB
parsed.entity_id = m.group(1)
parsed.details['hostname'] = m.group(2)
parsed.details['address_family'] = m.group(3)
return parsed
m = re.search(r"^Outstanding job (j\d+) for {hostname='([^']*)', address_"
"family=(\d+)}, which was started at t=(\d+)$", msg)
if m:
parsed.line_type = LINE_TYPE_OUTSTANDING_JOB
parsed.t = int(m.group(4))
parsed.entity_id = m.group(1)
parsed.details['hostname'] = m.group(2)
parsed.details['address_family'] = m.group(3)
return parsed
m = re.search(r"^Attached request (r\d+) to job (j\d+)$", msg)
if m:
parsed.line_type = LINE_TYPE_ATTACHED_REQUEST
parsed.entity_id = m.group(1)
parsed.details['job_id'] = m.group(2)
return parsed
m = re.search(r'^Finished request (r\d+) (.*)$', msg)
if m:
parsed.line_type = LINE_TYPE_FINISHED_REQUEST
parsed.entity_id = m.group(1)
parsed.details['extra'] = m.group(2)
return parsed
m = re.search(r'^Cancelled request (r\d+)$', msg)
if m:
parsed.line_type = LINE_TYPE_CANCELLED_REQUEST
parsed.entity_id = m.group(1)
return parsed
m = re.search(r'^Starting job (j\d+)$', msg)
if m:
parsed.line_type = LINE_TYPE_STARTING_JOB
parsed.entity_id = m.group(1)
return parsed
m = re.search(r'\[resolver thread\] Running job (j\d+)$', msg)
if m:
parsed.line_type = LINE_TYPE_RUNNING_JOB
parsed.entity_id = m.group(1)
return parsed
m = re.search(r'\[resolver thread\] Completed job (j\d+)$', msg)
if m:
parsed.line_type = LINE_TYPE_COMPLETED_JOB
parsed.entity_id = m.group(1)
return parsed
m = re.search(r'Completing job (j\d+).*$', msg)
if m:
parsed.line_type = LINE_TYPE_COMPLETING_JOB
parsed.entity_id = m.group(1)
return parsed
return None
def ParseFile(path):
"""Parses the file at |path| and returns a list of ParsedLines."""
f = open(path, 'r')
entries = []
for line in f:
parsed = ParseLine(line)
if parsed:
entries.append(parsed)
f.close()
return entries
|