ATLAS Offline Software
messageCounter.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
4 #
5 
6 '''
7 Script listing and counting Athena messages between two points in a log file,
8 typically between start and end of event loop.
9 '''
10 
11 from __future__ import print_function
12 import sys
13 import os
14 import re
15 import logging
16 import argparse
17 import json
18 from collections import OrderedDict
19 
20 
21 default_ignore_patterns = [
22  r'TrigCOOLUpd.*INFO.*Reload',
23  r'TrigCOOLUpd.*INFO.*Invalidated',
24  r'warn.*frontier.c.*Request',
25  r'warn.*frontier.c.*Trying',
26  r'AthenaHiveEventLoopMgr.*INFO.*processing event',
27  r'IOVDbFolder.*INFO.*tag.*resolved to',
28  r'IOVDbSvc.*INFO.*Opening.*connection',
29  r'IOVDbSvc.*INFO.*Disconnecting from',
30  r'RootDatabase\.open.*INFO.*File version',
31  r'Domain.*INFO.*DbDatabase',
32  r'INFO Database being retired',
33  r'StorageSvc.*INFO Building shape according to reflection information',
34 ]
35 
36 
37 def get_parser():
38  parser = argparse.ArgumentParser(usage='%(prog)s [options] LogFiles',
39  description=__doc__)
40  parser.add_argument('logfiles',
41  metavar='LogFiles',
42  nargs='+',
43  help='Log file(s) to analyse. Multiple space-separated file names may be given.')
44  parser.add_argument('-s', '--startPattern',
45  metavar='PATTERN',
46  help='Pattern to match start point for log analysis. If empty, log files are analysed from first line.')
47  parser.add_argument('-e', '--endPattern',
48  metavar='PATTERN',
49  help='Pattern to match end point for log analysis. If empty, log files are analysed until last line.')
50  parser.add_argument('-i', '--ignore',
51  metavar='PATTERN',
52  action='append',
53  default=[],
54  help='Add an ignore pattern to the default ones.' +
55  'The option can be specified multiple times. Defaults are: {:s}'.format(str(default_ignore_patterns)))
56  parser.add_argument('-p', '--printMessages',
57  action='store_true',
58  help='Print the messages found in analysed files')
59  parser.add_argument('--saveAll',
60  action='store_true',
61  help='Store all the messages into the output JSON file')
62  parser.add_argument('-v', '--verbose',
63  action='store_true',
64  help='Increase output verbosity')
65  return parser
66 
67 
68 def extract_messages(lines, start, end, ignore):
69  patterns = [re.compile(p) for p in ['FATAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'VERBOSE']]
70  result = OrderedDict()
71  for p in patterns:
72  result[p.pattern] = []
73  result['other'] = []
74  result['ignored'] = []
75 
76  running = False if start else True
77  for line in lines:
78  if not running and start and start.search(line):
79  running = True
80  continue
81  if running and end and end.search(line):
82  running = False
83  break
84  if running:
85  matched = False
86  ignored = False
87  for p in ignore:
88  if p.search(line):
89  result['ignored'].append(line)
90  ignored = True
91  break
92  if ignored:
93  continue
94  for p in patterns:
95  if p.search(line):
96  result[p.pattern].append(line)
97  matched = True
98  break
99  if not matched:
100  result['other'].append(line)
101 
102  return result
103 
104 
105 def make_summary(result):
106  summary = OrderedDict()
107  for p in result.keys():
108  summary[p] = len(result[p])
109  total = sum(summary.values())
110  summary['all'] = total
111  return summary
112 
113 
114 def print_result(summary, full_result, print_messages=False):
115  summary_str = 'Found the following number of messages:\n'
116  for p, n in summary.items():
117  summary_str += '{:8d} {:s} messages\n'.format(n, p)
118  logging.info(summary_str)
119  if print_messages:
120  for p, lines in full_result.items():
121  logging.info('##### The following %s messages were found #####', p)
122  for line in lines:
123  print(line, end='') # noqa: ATL901
124 
125 
126 def save_summary_to_json(result, filename):
127  logging.info('Saving results to %s', filename)
128  with open(filename, 'w') as f:
129  json.dump(result, f, indent=4)
130 
131 
132 def save_all_to_json(full_result, filename):
133  logging.info('Saving results to %s', filename)
134  with open(filename, 'w') as f:
135  json.dump(full_result, f, indent=4)
136 
137 
138 def main():
139  args = get_parser().parse_args()
140  logging.basicConfig(stream=sys.stdout,
141  format='messageCounter %(levelname)-8s %(message)s',
142  level=logging.DEBUG if args.verbose else logging.INFO)
143 
144  start = re.compile(args.startPattern) if args.startPattern else None
145  end = re.compile(args.endPattern) if args.endPattern else None
146  args.ignore.extend(default_ignore_patterns)
147  ignore = [re.compile(p) for p in args.ignore]
148 
149  for fname in args.logfiles:
150  if not os.path.isfile(fname):
151  logging.error('Cannot open file %s, skipping', fname)
152  continue
153  logging.info('Analysing file %s', fname)
154  with open(fname, encoding='utf-8') as f:
155  messages = extract_messages(f, start, end, ignore)
156  summary = make_summary(messages)
157  print_result(summary, messages, args.printMessages)
158  out_file_name = 'MessageCount.{:s}.json'.format(fname)
159  save_summary_to_json(summary, out_file_name)
160  if args.saveAll:
161  all_out_file_name = 'Messages.{:s}.json'.format(fname)
162  save_all_to_json(messages, all_out_file_name)
163 
164 
165 if '__main__' in __name__:
166  sys.exit(main())
messageCounter.make_summary
def make_summary(result)
Definition: messageCounter.py:105
vtune_athena.format
format
Definition: vtune_athena.py:14
messageCounter.save_summary_to_json
def save_summary_to_json(result, filename)
Definition: messageCounter.py:126
messageCounter.extract_messages
def extract_messages(lines, start, end, ignore)
Definition: messageCounter.py:68
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
messageCounter.print_result
def print_result(summary, full_result, print_messages=False)
Definition: messageCounter.py:114
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
messageCounter.main
def main()
Definition: messageCounter.py:138
messageCounter.save_all_to_json
def save_all_to_json(full_result, filename)
Definition: messageCounter.py:132
messageCounter.get_parser
def get_parser()
Definition: messageCounter.py:37
Trk::open
@ open
Definition: BinningType.h:40
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
confTool.parse_args
def parse_args()
Definition: confTool.py:35
str
Definition: BTagTrackIpAccessor.cxx:11