Merge lp:~matsubara/python-oops-datedir-repo/833857-blankline-reqvars into lp:python-oops-datedir-repo

Proposed by Diogo Matsubara
Status: Merged
Approved by: Robert Collins
Approved revision: 8
Merged at revision: 9
Proposed branch: lp:~matsubara/python-oops-datedir-repo/833857-blankline-reqvars
Merge into: lp:python-oops-datedir-repo
Diff against target: 108 lines (+60/-20)
2 files modified
oops_datedir_repo/serializer_rfc822.py (+29/-20)
oops_datedir_repo/tests/test_serializer_rfc822.py (+31/-0)
To merge this branch: bzr merge lp:~matsubara/python-oops-datedir-repo/833857-blankline-reqvars
Reviewer Review Type Date Requested Status
Robert Collins (community) Approve
Review via email: mp+72955@code.launchpad.net

Description of the change

This branch fixes the serializer to correctly parse request variables with a blank line between them as found in some ISD oops reports.

To post a comment you must log in.
8. By Diogo Matsubara

fix bug 833857 (serializer can't read isd oops report file)

Revision history for this message
Robert Collins (lifeless) wrote :

The fact lines is an iterator is eyewatering, but an existing thing. Thanks.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'oops_datedir_repo/serializer_rfc822.py'
2--- oops_datedir_repo/serializer_rfc822.py 2011-08-25 18:23:30 +0000
3+++ oops_datedir_repo/serializer_rfc822.py 2011-08-25 20:39:09 +0000
4@@ -93,33 +93,42 @@
5 # support iteration.
6 lines = iter(msg.fp)
7
8- # Request variables until the first blank line.
9+ def is_req_var(line):
10+ return "=" in line
11+
12+ def is_statement(line):
13+ return re.match(r'^(\d+)-(\d+)(?:@([\w-]+))?\s+(.*)', line)
14+
15+ def is_traceback(line):
16+ return 'traceback' in line.lower() or '== EXTRA DATA ==' in line
17+
18 req_vars = []
19- for line in lines:
20- line = line.strip()
21- if line == '':
22- break
23- key, value = line.split('=', 1)
24- req_vars.append((urllib.unquote(key), urllib.unquote(value)))
25-
26- # Statements until the next blank line.
27 statements = []
28+ first_tb_line = ''
29 for line in lines:
30 line = line.strip()
31 if line == '':
32- break
33- match = re.match(
34- r'^(\d+)-(\d+)(?:@([\w-]+))?\s+(.*)', line)
35- assert match is not None, (
36- "Unable to interpret oops line: %s" % line)
37- start, end, db_id, statement = match.groups()
38- if db_id is not None:
39- db_id = intern(db_id) # This string is repeated lots.
40- statements.append(
41- (int(start), int(end), db_id, statement))
42+ continue
43+ else:
44+ if is_req_var(line):
45+ key, value = line.split('=', 1)
46+ req_vars.append((urllib.unquote(key), urllib.unquote(value)))
47+ elif is_statement(line):
48+ match = re.match(
49+ r'^(\d+)-(\d+)(?:@([\w-]+))?\s+(.*)', line)
50+ assert match is not None, (
51+ "Unable to interpret oops line: %s" % line)
52+ start, end, db_id, statement = match.groups()
53+ if db_id is not None:
54+ db_id = intern(db_id) # This string is repeated lots.
55+ statements.append(
56+ (int(start), int(end), db_id, statement))
57+ elif is_traceback(line):
58+ first_tb_line = line
59+ break
60
61 # The rest is traceback.
62- tb_text = ''.join(lines)
63+ tb_text = ''.join([first_tb_line] + list(lines))
64
65 result = dict(id=id, type=exc_type, value=exc_value, time=date,
66 topic=topic, tb_text=tb_text, username=username, url=url,
67
68=== modified file 'oops_datedir_repo/tests/test_serializer_rfc822.py'
69--- oops_datedir_repo/tests/test_serializer_rfc822.py 2011-08-25 18:23:30 +0000
70+++ oops_datedir_repo/tests/test_serializer_rfc822.py 2011-08-25 20:39:09 +0000
71@@ -79,6 +79,37 @@
72 report['db_statements'][1],
73 (5, 10, 'store_b', 'SELECT 2'))
74
75+ def test_read_blankline_req_vars(self):
76+ """Test ErrorReport.read() for old logs with a blankline between
77+ reqvars."""
78+ fp = StringIO.StringIO(dedent("""\
79+ Oops-Id: OOPS-A0001
80+ Exception-Type: NotFound
81+ Exception-Value: error message
82+ Date: 2005-04-01T00:00:00+00:00
83+ Topic: IFoo:+foo-template
84+ User: Sample User
85+ URL: http://localhost:9000/foo
86+ Duration: 42
87+
88+ HTTP_USER_AGENT=Mozilla/5.0
89+
90+ HTTP_REFERER=http://localhost:9000/
91+ name%3Dfoo=hello%0Aworld
92+
93+ 00001-00005@store_a SELECT 1
94+ 00005-00010@store_b SELECT 2
95+
96+ traceback-text"""))
97+ report = read(fp)
98+ self.assertEqual(report['id'], 'OOPS-A0001')
99+ self.assertEqual(report['req_vars'][0], ('HTTP_USER_AGENT',
100+ 'Mozilla/5.0'))
101+ self.assertEqual(report['req_vars'][1], ('HTTP_REFERER',
102+ 'http://localhost:9000/'))
103+ self.assertEqual(report['req_vars'][2], ('name=foo', 'hello\nworld'))
104+ self.assertEqual(len(report['db_statements']), 2)
105+
106 def test_read_no_store_id(self):
107 """Test ErrorReport.read() for old logs with no store_id."""
108 fp = StringIO.StringIO(dedent("""\

Subscribers

People subscribed via source and target branches

to all changes: