Skip to content

Commit 8da95c3

Browse files
committed
Better validation and error reporting while processing logs.
Invalid log files could be undetected until much later, such as until they're being converted from .xz to .tar.xz in create_archive(). Now process_logs() performs some basic validation: the log must be readable (not bad gzip), not empty, and every line must be valid JSON. It also tries to read every log file instead of stopping at the first error, and prints the bad filenames and the exceptions at the end.
1 parent 2356d19 commit 8da95c3

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

votrfront/logutil.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import subprocess
1111
import sys
1212
import time
13+
import traceback
1314
from . import sessions
1415

1516

@@ -123,18 +124,28 @@ def set_tags(app, sessid, lineno, tags_to_add, tags_to_remove):
123124
def process_logfiles(app, files):
124125
c = _connect(app).cursor()
125126

127+
errors = []
128+
126129
for filename in files:
127130
sessid = os.path.basename(filename).partition('.')[0]
128-
with sessions.lock(app, sessid), open_log(filename) as f:
129-
lineno = 0
130-
for line in f:
131-
lineno += 1
132-
if re.search(BASE_PATTERN, line):
133-
try:
134-
c.execute('INSERT INTO lines VALUES (?, ?, ?, ?)',
135-
(sessid, lineno, 'new', line.strip()))
136-
except sqlite3.IntegrityError:
137-
pass # row already present
131+
with sessions.lock(app, sessid):
132+
try:
133+
with open_log(filename) as f:
134+
lineno = 0
135+
for line in f:
136+
json.loads(line) # Validate JSON.
137+
lineno += 1
138+
if re.search(BASE_PATTERN, line):
139+
try:
140+
c.execute(
141+
'INSERT INTO lines VALUES (?, ?, ?, ?)',
142+
(sessid, lineno, 'new', line.strip()))
143+
except sqlite3.IntegrityError:
144+
pass # row already present
145+
if lineno == 0:
146+
raise Exception('Log file is empty')
147+
except Exception:
148+
errors.append((filename, sys.exc_info()))
138149

139150
for line in get_lines(app):
140151
if line.tags == 'new':
@@ -144,6 +155,15 @@ def process_logfiles(app, files):
144155

145156
_connect(app).commit()
146157

158+
if errors:
159+
msgs = ['{} errors occurred while processing logs:'.format(len(errors))]
160+
for filename, exc_info in errors:
161+
errmsg = ''.join(traceback.format_exception(*exc_info))
162+
msgs.append(
163+
'{}:\n'.format(filename) +
164+
'\n'.join(' ' + line for line in errmsg.split('\n')))
165+
raise Exception('\n\n'.join(msgs))
166+
147167
@contextlib.contextmanager
148168
def wrap_pager():
149169
if os.isatty(0) and os.isatty(1):

0 commit comments

Comments
 (0)