Skip to content

Commit

Permalink
Better validation and error reporting while processing logs.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
TomiBelan committed Jun 4, 2019
1 parent 2356d19 commit 8da95c3
Showing 1 changed file with 30 additions and 10 deletions.
40 changes: 30 additions & 10 deletions votrfront/logutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import subprocess
import sys
import time
import traceback
from . import sessions


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

errors = []

for filename in files:
sessid = os.path.basename(filename).partition('.')[0]
with sessions.lock(app, sessid), open_log(filename) as f:
lineno = 0
for line in f:
lineno += 1
if re.search(BASE_PATTERN, line):
try:
c.execute('INSERT INTO lines VALUES (?, ?, ?, ?)',
(sessid, lineno, 'new', line.strip()))
except sqlite3.IntegrityError:
pass # row already present
with sessions.lock(app, sessid):
try:
with open_log(filename) as f:
lineno = 0
for line in f:
json.loads(line) # Validate JSON.
lineno += 1
if re.search(BASE_PATTERN, line):
try:
c.execute(
'INSERT INTO lines VALUES (?, ?, ?, ?)',
(sessid, lineno, 'new', line.strip()))
except sqlite3.IntegrityError:
pass # row already present
if lineno == 0:
raise Exception('Log file is empty')
except Exception:
errors.append((filename, sys.exc_info()))

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

_connect(app).commit()

if errors:
msgs = ['{} errors occurred while processing logs:'.format(len(errors))]
for filename, exc_info in errors:
errmsg = ''.join(traceback.format_exception(*exc_info))
msgs.append(
'{}:\n'.format(filename) +
'\n'.join(' ' + line for line in errmsg.split('\n')))
raise Exception('\n\n'.join(msgs))

@contextlib.contextmanager
def wrap_pager():
if os.isatty(0) and os.isatty(1):
Expand Down

0 comments on commit 8da95c3

Please sign in to comment.