288 def scanLogFile(self, resetReport=False):
289
290 nonStandardErrorsList = self.knowledgeFileHandler('nonStandardErrors.db')
291
292 if resetReport:
293 self.resetReport()
294
295 for log in self._logfile:
296 msg.debug('Now scanning logfile {0}'.format(log))
297 seenNonStandardError = ''
298 customLogParser = None
299 if log == 'log.generate':
300 from EvgenProdTools.EvgenParserTool import evgenParserTool
301 customLogParser = evgenParserTool()
302
303 try:
304 myGen = trfUtils.lineByLine(log, substepName=self._substepName)
305 except IOError as e:
306 msg.error('Failed to open transform logfile {0}: {1:s}'.format(log, e))
307
308 self._levelCounter['ERROR'] = 1
309 self._errorDetails['ERROR'] = {'message': str(e), 'firstLine': 0, 'count': 1}
310 return
311
312 inEventLoop = False
313 for line, lineCounter in myGen:
314 if '===>>> start processing event' in line: inEventLoop = True
315 if 'Application Manager Stopped successfully' in line: inEventLoop = False
316
317
318 if customLogParser is not None:
319 customLogParser.processLine(line)
320
321 m = self._metaPat.
search(line)
322 if m is not None:
323 key, value = m.groups()
324 self._metaData[key] = value
325
326 m = self._regExp.
match(line)
327 if m is None:
328
329
330 if 'Core dump from CoreDumpSvc' in line:
331 msg.warning('Detected CoreDumpSvc report - activating core dump svc grabber')
332 self.coreDumpSvcParser(log, myGen, line, lineCounter)
333 continue
334
335 if 'G4Exception-START' in line:
336 msg.warning('Detected G4 exception report - activating G4 exception grabber')
337 self.g4ExceptionParser(myGen, line, lineCounter, 40)
338 continue
339 if '*** G4Exception' in line:
340 msg.warning('Detected G4 9.4 exception report - activating G4 exception grabber')
341 self.g494ExceptionParser(myGen, line, lineCounter)
342 continue
343
344 if 'Shortened traceback (most recent user call last)' in line:
345 msg.warning('Detected python exception - activating python exception grabber')
346 self.pythonExceptionParser(log, myGen, line, lineCounter)
347 continue
348
349 if 'terminate called after throwing an instance of \'std::bad_alloc\'' in line:
350 msg.warning('Detected bad_alloc!')
351 self.badAllocExceptionParser(myGen, line, lineCounter)
352 continue
353
354
355 if 'Error in <TFile::ReadBuffer>' in line:
356 self.rootSysErrorParser(myGen, line, lineCounter)
357 continue
358
359 if 'Error in <TFile::WriteBuffer>' in line:
360 self.rootSysErrorParser(myGen, line, lineCounter)
361 continue
362
363 if any(line in l for l in nonStandardErrorsList):
364 seenNonStandardError = line
365 continue
366
367 msg.debug('Non-standard line in %s: %s', log, line)
368 self._levelCounter['UNKNOWN'] += 1
369 continue
370
371
372 fields = {}
373 for matchKey in ('service', 'level', 'message'):
374 fields[matchKey] = m.group(matchKey)
375 msg.debug('Line parsed as: {0}'.format(fields))
376
377
378
379 if (fields['level'] == 'WARNING') and inEventLoop:
380 self._eventLoopWarnings.append(fields)
381
382
383 ignoreFlag = False
384 for ignorePat in self._ignoreList.structuredPatterns:
385 serviceMatch = ignorePat[
'service'].
match(fields[
'service'])
386 levelMatch = (ignorePat['level'] == "" or ignorePat['level'] == fields['level'])
387 messageMatch = ignorePat[
'message'].
match(fields[
'message'])
388 if serviceMatch and levelMatch and messageMatch:
389 msg.info('Error message "{0}" was ignored at line {1} (structured match)'.format(line, lineCounter))
390 ignoreFlag = True
391 break
392 if ignoreFlag is False:
393 for searchPat in self._ignoreList.searchPatterns:
394 if searchPat.search(line):
395 msg.info('Error message "{0}" was ignored at line {1} (search match)'.format(line, lineCounter))
396 ignoreFlag = True
397 break
398 if ignoreFlag:
399
400 fields['level'] = 'IGNORED'
401 else:
402
403
404
405
406 if 'std::bad_alloc' in fields['message']:
407 fields['level'] = 'CATASTROPHE'
408
409
410 if fields['level'] == 'FATAL':
411 if seenNonStandardError:
412 line += '; ' + seenNonStandardError
413
414
415 self._levelCounter[fields['level']] += 1
416
417
418
419 if fields['level'] == 'IGNORED' or stdLogLevels[fields['level']] >= self._msgDetails:
420 if self._levelCounter[fields['level']] <= self._msgLimit:
421 detailsHandled = False
422 for seenError in self._errorDetails[fields['level']]:
423 if seenError['message'] == line:
424 seenError['count'] += 1
425 detailsHandled = True
426 break
427 if detailsHandled is False:
428 self._errorDetails[fields['level']].append({'message': line, 'firstLine': lineCounter, 'count': 1})
429 elif self._levelCounter[fields['level']] == self._msgLimit + 1:
430 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']))
431 else:
432
433 pass
434 if 'Total payload read from IOVDb' in fields['message']:
435 msg.debug("Found COOL payload information at line {0}".format(line))
436 a = re.match(r'(\D+)(?P<bytes>\d+)(\D+)(?P<time>\d+[.]?\d*)(\D+)', fields['message'])
437 self._dbbytes += int(a.group('bytes'))
438 self._dbtime += float(a.group('time'))
439
440 if customLogParser is not None:
441 customLogParser.report()
442 self._metaData = customLogParser.updateMetadata( self._metaData )
443
void search(TDirectory *td, const std::string &s, std::string cwd, node *n)
recursive directory search for TH1 and TH2 and TProfiles