218 def scanLogFile(self, resetReport=False):
219
220 nonStandardErrorsList = self.knowledgeFileHandler('nonStandardErrors.db')
221
222 if resetReport:
223 self.resetReport()
224
225 for log in self._logfile:
226 msg.debug('Now scanning logfile {0}'.format(log))
227 seenNonStandardError = ''
228 customLogParser = None
229 if log == 'log.generate':
230 from EvgenProdTools.EvgenParserTool import evgenParserTool
231 customLogParser = evgenParserTool()
232
233 try:
234 myGen = trfUtils.lineByLine(log, substepName=self._substepName)
235 except IOError as e:
236 msg.error('Failed to open transform logfile {0}: {1:s}'.format(log, e))
237
238 self._levelCounter['ERROR'] = 1
239 self._errorDetails['ERROR'] = {'message': str(e), 'firstLine': 0, 'count': 1}
240 return
241
242 inEventLoop = False
243 for line, lineCounter in myGen:
244 if '===>>> start processing event' in line: inEventLoop = True
245 if 'Application Manager Stopped successfully' in line: inEventLoop = False
246
247
248 if customLogParser is not None:
249 customLogParser.processLine(line)
250
251 m = self._metaPat.
search(line)
252 if m is not None:
253 key, value = m.groups()
254 self._metaData[key] = value
255
256 m = self._regExp.
match(line)
257 if m is None:
258
259
260 if 'Core dump from CoreDumpSvc' in line:
261 msg.warning('Detected CoreDumpSvc report - activating core dump svc grabber')
262 self.coreDumpSvcParser(log, myGen, line, lineCounter)
263 continue
264
265 if 'G4Exception-START' in line:
266 msg.warning('Detected G4 exception report - activating G4 exception grabber')
267 self.g4ExceptionParser(myGen, line, lineCounter, 40)
268 continue
269 if '*** G4Exception' in line:
270 msg.warning('Detected G4 9.4 exception report - activating G4 exception grabber')
271 self.g494ExceptionParser(myGen, line, lineCounter)
272 continue
273
274 if 'Shortened traceback (most recent user call last)' in line:
275 msg.warning('Detected python exception - activating python exception grabber')
276 self.pythonExceptionParser(log, myGen, line, lineCounter)
277 continue
278
279 if 'terminate called after throwing an instance of \'std::bad_alloc\'' in line:
280 msg.warning('Detected bad_alloc!')
281 self.badAllocExceptionParser(myGen, line, lineCounter)
282 continue
283
284
285 if 'Error in <TFile::ReadBuffer>' in line:
286 self.rootSysErrorParser(myGen, line, lineCounter)
287 continue
288
289 if 'Error in <TFile::WriteBuffer>' in line:
290 self.rootSysErrorParser(myGen, line, lineCounter)
291 continue
292
293 if any(line in l for l in nonStandardErrorsList):
294 seenNonStandardError = line
295 continue
296
297 msg.debug('Non-standard line in %s: %s', log, line)
298 self._levelCounter['UNKNOWN'] += 1
299 continue
300
301
302 fields = {}
303 for matchKey in ('service', 'level', 'message'):
304 fields[matchKey] = m.group(matchKey)
305 msg.debug('Line parsed as: {0}'.format(fields))
306
307
308
309 if (fields['level'] == 'WARNING') and inEventLoop:
310 self._eventLoopWarnings.append(fields)
311
312
313 ignoreFlag = False
314 for ignorePat in self._ignoreList.structuredPatterns:
315 serviceMatch = ignorePat[
'service'].
match(fields[
'service'])
316 levelMatch = (ignorePat['level'] == "" or ignorePat['level'] == fields['level'])
317 messageMatch = ignorePat[
'message'].
match(fields[
'message'])
318 if serviceMatch and levelMatch and messageMatch:
319 msg.info('Error message "{0}" was ignored at line {1} (structured match)'.format(line, lineCounter))
320 ignoreFlag = True
321 break
322 if ignoreFlag is False:
323 for searchPat in self._ignoreList.searchPatterns:
324 if searchPat.search(line):
325 msg.info('Error message "{0}" was ignored at line {1} (search match)'.format(line, lineCounter))
326 ignoreFlag = True
327 break
328 if ignoreFlag:
329
330 fields['level'] = 'IGNORED'
331 else:
332
333
334
335
336 if 'std::bad_alloc' in fields['message']:
337 fields['level'] = 'CATASTROPHE'
338
339
340 if fields['level'] == 'FATAL':
341 if seenNonStandardError:
342 line += '; ' + seenNonStandardError
343
344
345 self._levelCounter[fields['level']] += 1
346
347
348
349 if fields['level'] == 'IGNORED' or stdLogLevels[fields['level']] >= self._msgDetails:
350 if self._levelCounter[fields['level']] <= self._msgLimit:
351 detailsHandled = False
352 for seenError in self._errorDetails[fields['level']]:
353 if seenError['message'] == line:
354 seenError['count'] += 1
355 detailsHandled = True
356 break
357 if detailsHandled is False:
358 self._errorDetails[fields['level']].append({'message': line, 'firstLine': lineCounter, 'count': 1})
359 elif self._levelCounter[fields['level']] == self._msgLimit + 1:
360 msg.warning("Found message number {0} at level {1} - this and further messages will be supressed from the report".format(self._levelCounter[fields['level']], fields['level']))
361 else:
362
363 pass
364 if 'Total payload read from IOVDb' in fields['message']:
365 msg.debug("Found COOL payload information at line {0}".format(line))
366 a = re.match(r'(\D+)(?P<bytes>\d+)(\D+)(?P<time>\d+[.]?\d*)(\D+)', fields['message'])
367 self._dbbytes += int(a.group('bytes'))
368 self._dbtime += float(a.group('time'))
369
370 if customLogParser is not None:
371 customLogParser.report()
372 self._metaData = customLogParser.updateMetadata( self._metaData )
373
void search(TDirectory *td, const std::string &s, std::string cwd, node *n)
recursive directory search for TH1 and TH2 and TProfiles