5 """Tool to check for error messages in a log file.
7 By default ERROR, FATAL and CRITICAL messages are considered.
8 The config file may be used to provide patterns of lines to exclude from this check
9 (known problems or false positives). If no config file is provided, all errors will be shown."""
18 regexMap[
'error/fatal'] = [
19 r'^ERROR ',
'^ERROR:',
' ERROR ',
' FATAL ',
'CRITICAL ',
'ABORT_CHAIN',
23 r'tcmalloc\: allocation failed',
24 r'athenaHLT.py\: error',
25 r'HLTMPPU.*Child Issue',
26 r'HLTMPPU.*Configuration Issue',
28 r'illegal instruction',
29 r'failure loading library',
30 r'Cannot allocate memory',
31 r'Attempt to free invalid pointer',
35 regexMap[
'prohibited'] = [
36 r'inconsistent use of tabs and spaces in indentation',
38 r'in state: CONTROLREADY$',
39 r'(^\s*|^\d\d:\d\d:\d\d\s*)missing data: ',
40 r'(^\s*|^\d\d:\d\d:\d\d\s*)missing conditions data: ',
41 r'(^\s*|^\d\d:\d\d:\d\d\s*)can be produced by alg\(s\): ',
42 r'(^\s*|^\d\d:\d\d:\d\d\s*)required by tool: ',
43 r'pure virtual method called',
44 r'Selected dynamic Aux atribute.*not found in the registry',
48 r'FPEAuditor.*WARNING FPE',
53 builtins =
dir(builtins)
54 builtinErrors = [b
for b
in builtins
if 'Error' in b]
55 regexMap[
'python error'] = builtinErrors
60 r'Shortened traceback',
65 regexMap[
'backtrace'] = backtrace
68 fpeTracebackStart = [
r'FPEAuditor.*INFO FPE stacktrace']
74 regexMap[
'fpe'].
extend(fpeTracebackStart)
77 regexMap[
'warning'] = [
'WARNING ']
79 for key,exprlist
in regexMap.items():
81 raise RuntimeError(f
'Empty regex list for category \'{key}\' -- will match everything!')
85 parser = argparse.ArgumentParser(description=__doc__, formatter_class=
86 lambda prog : argparse.HelpFormatter(
87 prog, max_help_position=40, width=100))
89 parser.add_argument(
'logfile', metavar=
'<logfile>', nargs=
'+',
90 help=
'log file(s) to scan')
91 parser.add_argument(
'--config', metavar=
'<file>',
92 help=
'specify config file')
93 parser.add_argument(
'--showexcludestats', action=
'store_true',
94 help=
'print summary table with number of matches for each exclude pattern')
95 parser.add_argument(
'--printpatterns', action=
'store_true',
96 help=
'print the list of warning/error patterns being searched for')
97 parser.add_argument(
'--warnings', action =
'store_true',
98 help=
'check for WARNING messages')
99 parser.add_argument(
'--errors', action =
'store_true',
100 help=
'check for ERROR messages')
108 args = parser.parse_args()
109 if not (args.errors
or args.warnings):
110 parser.error(
'at least one of --errors or --warnings must be enabled')
112 ignorePattern =
parseConfig(args)
if args.config
else []
114 for i, lf
in enumerate(args.logfile):
123 """Parses the config file provided into a list (ignorePattern)"""
126 os.system(f
"get_files -data -symlink {args.config} > /dev/null")
127 with open(args.config)
as f:
128 print(
'Ignoring warnings/error patterns defined in ' + args.config)
130 if 'ignore' in aline:
131 line = aline.strip(
'ignore').strip()
132 if line.startswith(
'\'')
and line.endswith(
'\''):
134 ignorePattern.append(line)
139 """Scan one log file and print report"""
140 tPattern = re.compile(
'|'.
join(backtrace))
141 fpeStartPattern = re.compile(
'|'.
join(fpeTracebackStart))
142 fpeContPattern = re.compile(
'|'.
join(fpeTracebackCont))
146 if args.warnings
is True:
147 categories += [
'warning']
148 if args.errors
is True:
149 categories += [
'error/fatal',
'prohibited',
'python error',
'fpe',
'backtrace']
151 igLevels = re.compile(
'|'.
join(ignorePattern))
154 cat: re.compile(
'|'.
join(regexMap[cat]))
for cat
in categories
156 resultsA = {cat:[]
for cat
in categories}
157 with open(logfile, encoding=
'utf-8')
as f:
165 if tPattern.search(line)
and not igLevels.search(line):
167 elif fpeStartPattern.search(line)
and not igLevels.search(line):
175 resultsA[
'backtrace'].
append(line)
178 if fpeStartPattern.search(line)
or fpeContPattern.search(line):
179 resultsA[
'fpe'].
append(line)
183 for cat
in categories:
184 if patterns[cat].
search(line):
185 resultsA[cat].
append(line)
188 results = {cat:[]
for cat
in categories}
189 if args.config
is None:
192 if args.showexcludestats:
193 separateIgnoreRegex = [re.compile(line)
for line
in ignorePattern]
194 ignoreDict = {line:0
for line
in ignorePattern}
197 for cat, messages
in resultsA.items():
199 if not igLevels.search(res):
201 elif args.showexcludestats:
202 for i
in range(len(separateIgnoreRegex)):
203 if separateIgnoreRegex[i].
search(res):
204 ignoreDict[ignorePattern[i]] += 1
208 found_bad_message =
False
209 for cat
in categories:
211 if args.printpatterns:
212 print(f
'check_log.py - Checking for {cat} messages with pattern: {str(patterns[cat])} in '+logfile+
'\n')
213 if len(results[cat]) > 0:
214 print(f
'Found {len(results[cat])} {cat} message(s) in {logfile}:')
215 for msg
in results[cat]:
print(msg.strip(
'\n'))
216 found_bad_message =
True
221 if ignoreDict[s] > 0:
222 print(
str(ignoreDict[s]) +
"x " + s)
225 if found_bad_message:
226 print(f
'FAILURE : problematic message found in {logfile}')
229 print(f
'No error/warning messages found in {logfile}')
233 if __name__ ==
"__main__":