CMS 3D CMS Logo

ELstatistics.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // ELstatistics.cc
4 //
5 // History:
6 // 7/8/98 mf Created
7 // 7/2/99 jv Added noTerminationSummary() function
8 // 6/7/00 web Reflect consolidation of ELdestination/X;
9 // consolidate ELstatistics/X
10 // 6/14/00 web Remove GNU relic code
11 // 6/15/00 web using -> USING
12 // 10/4/00 mf filterModule() and excludeModule()
13 // 3/13/00 mf statisticsMap()
14 // 4/4/01 mf Simplify filter/exclude logic by useing base class
15 // method thisShouldBeIgnored(). Eliminate
16 // moduleOfinterest and moduleToexclude.
17 // 11/01/01 web Remove last vestige of GNU relic code; reordered
18 // initializers to correspond to order of member
19 // declarations
20 // 1/17/06 mf summary() for use in MessageLogger
21 // 8/16/07 mf Changes to implement grouping of modules in specified
22 // categories
23 // 6/19/08 mf summaryForJobReport()
24 //
25 // ---------------------------------------------------------------------
26 
28 
30 
31 #include <iostream>
32 #include <iomanip>
33 #include <sstream>
34 #include <ios>
35 #include <cassert>
36 
37 // Possible Traces:
38 // #define ELstatisticsCONSTRUCTOR_TRACE
39 // #define ELstatsLOG_TRACE
40 
41 namespace {
42  std::string summarizeContext(const std::string& c) {
43  if (c.substr(0, 4) != "Run:")
44  return c;
45  std::istringstream is(c);
46  std::string runWord;
47  int run;
48  is >> runWord >> run;
49  if (!is)
50  return c;
51  if (runWord != "Run:")
52  return c;
53  std::string eventWord;
54  int event;
55  is >> eventWord >> event;
56  if (!is)
57  return c;
58  if (eventWord != "Event:")
59  return c;
60  std::ostringstream os;
61  os << run << "/" << event;
62  return os.str();
63  }
64 } // namespace
65 
66 using namespace edm::messagelogger;
67 
68 namespace edm {
69  namespace service {
70 
71  // ----------------------------------------------------------------------
72  // Constructors
73  // ----------------------------------------------------------------------
74 
75  ELstatistics::ELstatistics()
76  : ELdestination(),
77  tableLimit(-1),
78  stats(),
79  updatedStats(false),
80  termStream(std::cerr),
81  printAtTermination(true) {
82 #ifdef ELstatisticsCONSTRUCTOR_TRACE
83  std::cerr << "Constructor for ELstatistics()\n";
84 #endif
85 
86  } // ELstatistics()
87 
88  ELstatistics::ELstatistics(std::ostream& osp)
89  : ELdestination(), tableLimit(-1), stats(), updatedStats(false), termStream(osp), printAtTermination(true) {
90 #ifdef ELstatisticsCONSTRUCTOR_TRACE
91  std::cerr << "Constructor for ELstatistics(osp)\n";
92 #endif
93 
94  } // ELstatistics()
95 
97  : ELdestination(),
98  tableLimit(spaceLimit),
99  stats(),
100  updatedStats(false),
101  termStream(std::cerr),
102  printAtTermination(true) {
103 #ifdef ELstatisticsCONSTRUCTOR_TRACE
104  std::cerr << "Constructor for ELstatistics(spaceLimit)\n";
105 #endif
106 
107  } // ELstatistics()
108 
109  ELstatistics::ELstatistics(int spaceLimit, std::ostream& osp)
110  : ELdestination(),
111  tableLimit(spaceLimit),
112  stats(),
113  updatedStats(false),
114  termStream(osp),
115  printAtTermination(true) {
116 #ifdef ELstatisticsCONSTRUCTOR_TRACE
117  std::cerr << "Constructor for ELstatistics(spaceLimit,osp)\n";
118 #endif
119 
120  } // ELstatistics()
121 
123  : ELdestination(),
124  tableLimit(orig.tableLimit),
125  stats(orig.stats),
126  updatedStats(orig.updatedStats),
127  termStream(orig.termStream),
128  printAtTermination(orig.printAtTermination) {
129 #ifdef ELstatisticsCONSTRUCTOR_TRACE
130  std::cerr << "Copy constructor for ELstatistics()\n";
131 #endif
132 
136  ignoreThese = orig.ignoreThese;
137 
138  } // ELstatistics()
139 
141 #ifdef ELstatisticsCONSTRUCTOR_TRACE
142  std::cerr << "Destructor for ELstatistics\n";
143 #endif
144 
146  summary(termStream, "Termination Summary");
147 
148  } // ~ELstatistics()
149 
150  // ----------------------------------------------------------------------
151  // Methods invoked by the ELadministrator
152  // ----------------------------------------------------------------------
153 
155 #ifdef ELstatsLOG_TRACE
156  std::cerr << " =:=:=: Log to an ELstatistics\n";
157 #endif
158 
159  // See if this message is to be counted.
160 
161  if (msg.xid().severity < threshold)
162  return false;
163  if (thisShouldBeIgnored(msg.xid().module))
164  return false;
165 
166  // Account for this message, making a new table entry if needed:
167  //
168  ELmap_stats::iterator s = stats.find(msg.xid());
169  if (s == stats.end()) {
170  if (tableLimit < 0 || static_cast<int>(stats.size()) < tableLimit) {
171  stats[msg.xid()] = StatsCount();
172  s = stats.find(msg.xid());
173  }
174  }
175 #ifdef ELstatsLOG_TRACE
176  std::cerr << " =:=:=: Message accounted for in stats \n";
177 #endif
178  if (s != stats.end()) {
179  (*s).second.add(summarizeContext(msg.context()), msg.reactedTo());
180 
181  updatedStats = true;
182 #ifdef ELstatsLOG_TRACE
183  std::cerr << " =:=:=: Updated stats \n";
184 #endif
185  }
186 
187  // For the purposes of telling whether any log destination has reacted
188  // to the message, the statistics destination does not count:
189  //
190 
191 #ifdef ELstatsLOG_TRACE
192  std::cerr << " =:=:=: log(msg) done (stats) \n";
193 #endif
194 
195  return false;
196 
197  } // log()
198 
200  limits.zero();
201  ELmap_stats::iterator s;
202  for (s = stats.begin(); s != stats.end(); ++s) {
203  (*s).second.n = 0;
204  (*s).second.context1 = (*s).second.context2 = (*s).second.contextLast = "";
205  }
206 
207  } // clearSummary()
208 
210  limits.wipe();
211  stats.erase(stats.begin(), stats.end()); //stats.clear();
212 
213  } // wipe()
214 
215  void ELstatistics::zero() { limits.zero(); } // zero()
216 
218  // Major changes 8/16/07 mf, including making this
219  // a static member function instead of a free function
220 
221  using std::ios; /* _base ? */
222  using std::left;
223  using std::right;
224  using std::setw;
225 
226  std::ostringstream s;
227  int n = 0;
228 
229  // ----- Summary part I:
230  //
231  bool ftnote(false);
232 
233  struct part3 {
234  long n, t;
235  part3() : n(0L), t(0L) { ; }
237 
238  std::set<std::string>::iterator gcEnd = groupedCategories.end();
239  std::set<std::string> gCats = groupedCategories; // TEMP FOR DEBUGGING SANITY
240  for (ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i) {
241  // If this is a grouped category, wait till later to output its stats
242  std::string cat = (*i).first.id;
243  if (groupedCategories.find(cat) != gcEnd) { // 8/16/07 mf
244  continue; // We will process these categories later
245  }
246 
247  // ----- Emit new process and part I header, if needed:
248  //
249  if (n == 0) {
250  s << "\n";
251  s << " type category sev module "
252  " subroutine count total\n"
253  << " ---- -------------------- -- ------------------------- "
254  "--------------------- ----- -----\n";
255  }
256  // ----- Emit detailed message information:
257  //
258  s << right << std::setw(5) << ++n << ' ' << left << std::setw(20) << (*i).first.id.substr(0, 20) << ' ' << left
259  << std::setw(2) << (*i).first.severity.getSymbol() << ' ' << left << std::setw(25)
260  << (*i).first.module.substr(0, 25) << ' ' << left << std::setw(21) << (*i).first.subroutine.substr(0, 21)
261  << right << std::setw(7) << (*i).second.n << left << std::setw(1) << ((*i).second.ignoredFlag ? '*' : ' ')
262  << right << std::setw(8) << (*i).second.aggregateN << '\n';
263  ftnote = ftnote || (*i).second.ignoredFlag;
264 
265  // ----- Obtain information for Part III, below:
266  //
267  ELextendedID xid = (*i).first;
268  p3[xid.severity.getLevel()].n += (*i).second.n;
269  p3[xid.severity.getLevel()].t += (*i).second.aggregateN;
270  } // for i
271 
272  // ----- Part Ia: The grouped categories
273  for (std::set<std::string>::iterator g = groupedCategories.begin(); g != gcEnd; ++g) {
274  int groupTotal = 0;
275  int groupAggregateN = 0;
277  bool groupIgnored = true;
278  for (ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i) {
279  if ((*i).first.id == *g) {
280  if (groupTotal == 0)
281  severityLevel = (*i).first.severity;
282  groupIgnored &= (*i).second.ignoredFlag;
283  groupAggregateN += (*i).second.aggregateN;
284  ++groupTotal;
285  }
286  } // for i
287  if (groupTotal > 0) {
288  // ----- Emit detailed message information:
289  //
290  s << right << std::setw(5) << ++n << ' ' << left << std::setw(20) << (*g).substr(0, 20) << ' ' << left
291  << std::setw(2) << severityLevel.getSymbol() << ' ' << left << std::setw(16) << " <Any Module> " << ' '
292  << left << std::setw(16) << "<Any Function>" << right << std::setw(7) << groupTotal << left << std::setw(1)
293  << (groupIgnored ? '*' : ' ') << right << std::setw(8) << groupAggregateN << '\n';
294  ftnote = ftnote || groupIgnored;
295 
296  // ----- Obtain information for Part III, below:
297  //
298  int lev = severityLevel.getLevel();
299  p3[lev].n += groupTotal;
300  p3[lev].t += groupAggregateN;
301  } // end if groupTotal>0
302  } // for g
303 
304  // ----- Provide footnote to part I, if needed:
305  //
306  if (ftnote)
307  s << "\n* Some occurrences of this message"
308  " were suppressed in all logs, due to limits.\n";
309 
310  // ----- Summary part II:
311  //
312  n = 0;
313  for (ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i) {
314  std::string cat = (*i).first.id;
315  if (groupedCategories.find(cat) != gcEnd) { // 8/16/07 mf
316  continue; // We will process these categories later
317  }
318  if (n == 0) {
319  s << '\n'
320  << " type category Examples: "
321  "run/evt run/evt run/evt\n"
322  << " ---- -------------------- ----"
323  "------------ ---------------- ----------------\n";
324  }
325  s << right << std::setw(5) << ++n << ' ' << left << std::setw(20) << (*i).first.id.c_str() << ' ' << left
326  << std::setw(16) << (*i).second.context1.c_str() << ' ' << left << std::setw(16)
327  << (*i).second.context2.c_str() << ' ' << (*i).second.contextLast.c_str() << '\n';
328  } // for
329 
330  // ----- Summary part III:
331  //
332  s << "\nSeverity # Occurrences Total Occurrences\n"
333  << "-------- ------------- -----------------\n";
334  for (int k = 0; k < ELseverityLevel::nLevels; ++k) {
335  if (p3[k].n != 0 || p3[k].t != 0) {
336  s << left << std::setw(8) << ELseverityLevel(ELseverityLevel::ELsev_(k)).getName().c_str() << right
337  << std::setw(17) << p3[k].n << right << std::setw(20) << p3[k].t << '\n';
338  }
339  } // for
340 
341  return s.str();
342 
343  } // formSummary()
344 
345  void ELstatistics::summary(std::ostream& os, std::string_view title) {
346  os << title << std::endl << formSummary(stats) << std::flush;
347  updatedStats = false;
348 
349  } // summary()
350 
351  void ELstatistics::summary(unsigned long overfullWaitCount) {
352  termStream << "\n=============================================\n\n"
353  << "MessageLogger Summary" << std::endl
354  << formSummary(stats) << std::endl
355  << "dropped waiting message count " << overfullWaitCount << std::endl
356  << std::flush;
357  updatedStats = false;
358 
359  } // summary()
360 
362 
363  std::map<ELextendedID, StatsCount> ELstatistics::statisticsMap() const {
364  return std::map<ELextendedID, StatsCount>(stats);
365  }
366 
367  // 6/19/08 mf
368  void ELstatistics::summaryForJobReport(std::map<std::string, double>& sm) {
369  struct part3 {
370  long n, t;
371  part3() : n(0L), t(0L) { ; }
373 
374  std::set<std::string>::iterator gcEnd = groupedCategories.end();
375  std::set<std::string> gCats = groupedCategories; // TEMP FOR DEBUGGING SANITY
376 
377  // ----- Part I: The ungrouped categories
378  for (ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i) {
379  // If this is a grouped category, wait till later to output its stats
380  std::string cat = (*i).first.id;
381  if (groupedCategories.find(cat) != gcEnd) {
382  continue; // We will process these categories later
383  }
384 
385  // ----- Emit detailed message information:
386  //
387  std::ostringstream s;
388  s << "Category_";
389  std::string sevSymbol = (*i).first.severity.getSymbol();
390  if (sevSymbol[0] == '-')
391  sevSymbol = sevSymbol.substr(1);
392  s << sevSymbol << "_" << (*i).first.id;
393  int n = (*i).second.aggregateN;
394  std::string catstr = s.str();
395  if (sm.find(catstr) != sm.end()) {
396  sm[catstr] += n;
397  } else {
398  sm[catstr] = n;
399  }
400  // ----- Obtain information for Part III, below:
401  //
402  ELextendedID xid = (*i).first;
403  p3[xid.severity.getLevel()].n += (*i).second.n;
404  p3[xid.severity.getLevel()].t += (*i).second.aggregateN;
405  } // for i
406 
407  // ----- Part Ia: The grouped categories
408  for (std::set<std::string>::iterator g = groupedCategories.begin(); g != gcEnd; ++g) {
409  int groupTotal = 0;
410  int groupAggregateN = 0;
412  for (ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i) {
413  if ((*i).first.id == *g) {
414  if (groupTotal == 0)
415  severityLevel = (*i).first.severity;
416  groupAggregateN += (*i).second.aggregateN;
417  ++groupTotal;
418  }
419  } // for i
420  if (groupTotal > 0) {
421  // ----- Emit detailed message information:
422  //
423  std::ostringstream s;
424  s << "Category_";
425  std::string sevSymbol = severityLevel.getSymbol();
426  if (sevSymbol[0] == '-')
427  sevSymbol = sevSymbol.substr(1);
428  s << sevSymbol << "_" << *g;
429  int n = groupAggregateN;
430  std::string catstr = s.str();
431  if (sm.find(catstr) != sm.end()) {
432  sm[catstr] += n;
433  } else {
434  sm[catstr] = n;
435  }
436 
437  // ----- Obtain information for Part III, below:
438  //
439  int lev = severityLevel.getLevel();
440  p3[lev].n += groupTotal;
441  p3[lev].t += groupAggregateN;
442  } // end if groupTotal>0
443  } // for g
444 
445  // part II (sample event numbers) does not exist for the job report.
446 
447  // ----- Summary part III:
448  //
449  for (int k = 0; k < ELseverityLevel::nLevels; ++k) {
450  //if ( p3[k].t != 0 ) {
451  if (true) {
452  std::string sevName;
454  if (sevName == "Severe")
455  sevName = "System";
456  if (sevName == "Success")
457  sevName = "Debug";
458  sevName = std::string("Log") + sevName;
459  sevName = dualLogName(sevName);
460  if (sevName != "UnusedSeverity") {
461  sm[sevName] = p3[k].t;
462  }
463  }
464  } // for k
465 
466  } // summaryForJobReport()
467 
469  if (s == "LogDebug")
470  return "LogDebug_LogTrace";
471  if (s == "LogInfo")
472  return "LogInfo_LogVerbatim";
473  if (s == "LogWarning")
474  return "LogWarnng_LogPrint";
475  if (s == "LogError")
476  return "LogError_LogProblem";
477  if (s == "LogSystem")
478  return "LogSystem_LogAbsolute";
479  return "UnusedSeverity";
480  }
481 
482  std::set<std::string> ELstatistics::groupedCategories; // 8/16/07 mf
483 
485 
486  } // end of namespace service
487 } // end of namespace edm
std::map< ELextendedID, StatsCount > statisticsMap() const
static std::set< std::string > groupedCategories
Definition: ELstatistics.h:97
messagelogger::ELseverityLevel severity
Definition: ELextendedID.h:30
std::unordered_set< std::string > ignoreThese
std::string dualLogName(std::string const &s)
std::string_view getName() const noexcept
std::ostream & termStream
Definition: ELstatistics.h:93
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
constexpr int getLevel() const noexcept
void summary(unsigned long overfullWaitCount)
def cat(path)
Definition: eostools.py:401
static void noteGroupedCategory(std::string const &cat)
std::unordered_set< std::string > respondToThese
bool log(const edm::ErrorObj &msg) override
tuple msg
Definition: mps_check.py:286
HLT enums.
virtual bool thisShouldBeIgnored(std::string const &s) const
void summaryForJobReport(std::map< std::string, double > &sm)
messagelogger::ELseverityLevel threshold
static std::string formSummary(ELmap_stats &stats)
std::map< ELextendedID, StatsCount > ELmap_stats
Definition: ELmap.h:88