Skip to content

Instantly share code, notes, and snippets.

@danielgoncalves
Last active Dec 13, 2015
Embed
What would you like to do?
Minimalist tool to search and list occurrences of unique exceptions in log files. The exceptions should be logged using the `exception` method.
# -*- coding: utf-8 -*-
#
# logr.py is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# logr.py is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with logr.py. If not, see <http://www.gnu.org/licenses/>.
#
"""
Minimalist tool to search and list occurrences of unique exceptions in log
files. The exceptions should be logged using the `exception` method.
Usage example::
python logr.py /path/to/file.log
Sample output::
Total 115432 line(s)
Found 3 unique exception(s)...
IOError 4 occurrence(s) at line(s):
65227, 81122, 108628, 112905
RuntimeError 5709 occurrence(s) at line(s):
3, 16, 29, 42, 55, 68, 82, 95, 130, 143, 156, 169, 182, 195, 208, ...
IntegrityError 1472 occurrence(s) at line(s):
108, 247, 322, 382, 545, 594, 693, 715, 763, 796, 946, 982, 1133, 1168,
1201, ...
"""
import argparse
import re
import textwrap
VERSION = '0.1'
BEGIN_TRACEBACK = re.compile(r'^Traceback \(most recent call last\)\:')
EXCEPTION_MESSAGE = re.compile(r'^(?P<exc_name>\w+)\:(?P<exc_message>.*)')
def logr_list_exceptions(filename, maxlines=0):
exc_map = {}
in_traceback = False
traceback_line = 0
with open(filename, 'rb') as fhandler:
line_num = 0
for line in fhandler:
line_num += 1
if BEGIN_TRACEBACK.match(line):
in_traceback = True
traceback_line = line_num
if in_traceback:
matcher = EXCEPTION_MESSAGE.match(line)
if matcher is not None:
exc_name = matcher.group('exc_name')
exc_message = matcher.group('exc_message')
if exc_name in exc_map:
data = exc_map[exc_name]
data['count'] += 1
data['lines'].append(traceback_line)
else:
data = {'count': 1, 'lines': [traceback_line,]}
exc_map[exc_name] = data
in_traceback = False
traceback_line = 0
print 'Total', line_num, 'line(s)'
if exc_map:
print 'Found %d unique exception(s)...' % len(exc_map)
print
for exc_name, data in exc_map.iteritems():
print exc_name, data['count'], 'occurrence(s) at line(s):'
if maxlines > 0:
lines = data['lines'][:maxlines]
else:
lines = data['lines']
ellipses = ', ...' if len(lines) < len(data['lines']) else ''
p = ', '.join([str(n) for n in lines]) + ellipses
for line in textwrap.wrap(p, 75):
print ' ', line
print
else:
print 'No tracebacks found.'
if __name__ == '__main__':
version = '%%(prog)s %s' % VERSION
parser = argparse.ArgumentParser(
prog='logr',
description='Search for exceptions in log files')
parser.add_argument('filename',
help='The log file to search.')
parser.add_argument('--version', action='version', version=version)
parser.add_argument('-m', '--maxlines', type=int,
default=15,
action='store',
help='Max line numbers to display (defaults to %(default)d, use 0 to display all)')
args = parser.parse_args()
logr_list_exceptions(args.filename, maxlines=args.maxlines)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment