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 edm {
42  namespace service {
43 
44  // ----------------------------------------------------------------------
45  // Constructors
46  // ----------------------------------------------------------------------
47 
49  : ELdestination(),
50  tableLimit(-1),
51  stats(),
52  updatedStats(false),
53  termStream(std::cerr),
54  printAtTermination(true) {
55 #ifdef ELstatisticsCONSTRUCTOR_TRACE
56  std::cerr << "Constructor for ELstatistics()\n";
57 #endif
58 
59  } // ELstatistics()
60 
61  ELstatistics::ELstatistics(std::ostream& osp)
63 #ifdef ELstatisticsCONSTRUCTOR_TRACE
64  std::cerr << "Constructor for ELstatistics(osp)\n";
65 #endif
66 
67  } // ELstatistics()
68 
70  : ELdestination(),
71  tableLimit(spaceLimit),
72  stats(),
76 #ifdef ELstatisticsCONSTRUCTOR_TRACE
77  std::cerr << "Constructor for ELstatistics(spaceLimit)\n";
78 #endif
79 
80  } // ELstatistics()
81 
82  ELstatistics::ELstatistics(int spaceLimit, std::ostream& osp)
83  : ELdestination(),
84  tableLimit(spaceLimit),
85  stats(),
87  termStream(osp),
89 #ifdef ELstatisticsCONSTRUCTOR_TRACE
90  std::cerr << "Constructor for ELstatistics(spaceLimit,osp)\n";
91 #endif
92 
93  } // ELstatistics()
94 
96  : ELdestination(),
97  tableLimit(orig.tableLimit),
98  stats(orig.stats),
100  termStream(orig.termStream),
102 #ifdef ELstatisticsCONSTRUCTOR_TRACE
103  std::cerr << "Copy constructor for ELstatistics()\n";
104 #endif
105 
109  ignoreThese = orig.ignoreThese;
110 
111  } // ELstatistics()
112 
114 #ifdef ELstatisticsCONSTRUCTOR_TRACE
115  std::cerr << "Destructor for ELstatistics\n";
116 #endif
117 
119  summary(termStream, "Termination Summary");
120 
121  } // ~ELstatistics()
122 
123  // ----------------------------------------------------------------------
124  // Methods invoked by the ELadministrator
125  // ----------------------------------------------------------------------
126 
128  if (c.substr(0, 4) != "Run:")
129  return c;
130  std::istringstream is(c);
131  std::string runWord;
132  int run;
133  is >> runWord >> run;
134  if (!is)
135  return c;
136  if (runWord != "Run:")
137  return c;
138  std::string eventWord;
139  int event;
140  is >> eventWord >> event;
141  if (!is)
142  return c;
143  if (eventWord != "Event:")
144  return c;
145  std::ostringstream os;
146  os << run << "/" << event;
147  return os.str();
148  }
149 
151 #ifdef ELstatsLOG_TRACE
152  std::cerr << " =:=:=: Log to an ELstatistics\n";
153 #endif
154 
155  // See if this message is to be counted.
156 
157  if (msg.xid().severity < threshold)
158  return false;
159  if (thisShouldBeIgnored(msg.xid().module))
160  return false;
161 
162  // Account for this message, making a new table entry if needed:
163  //
164  ELmap_stats::iterator s = stats.find(msg.xid());
165  if (s == stats.end()) {
166  if (tableLimit < 0 || static_cast<int>(stats.size()) < tableLimit) {
167  stats[msg.xid()] = StatsCount();
168  s = stats.find(msg.xid());
169  }
170  }
171 #ifdef ELstatsLOG_TRACE
172  std::cerr << " =:=:=: Message accounted for in stats \n";
173 #endif
174  if (s != stats.end()) {
175  (*s).second.add(summarizeContext(msg.context()), msg.reactedTo());
176 
177  updatedStats = true;
178 #ifdef ELstatsLOG_TRACE
179  std::cerr << " =:=:=: Updated stats \n";
180 #endif
181  }
182 
183  // For the purposes of telling whether any log destination has reacted
184  // to the message, the statistics destination does not count:
185  //
186 
187 #ifdef ELstatsLOG_TRACE
188  std::cerr << " =:=:=: log(msg) done (stats) \n";
189 #endif
190 
191  return false;
192 
193  } // log()
194 
196  limits.zero();
197  ELmap_stats::iterator s;
198  for (s = stats.begin(); s != stats.end(); ++s) {
199  (*s).second.n = 0;
200  (*s).second.context1 = (*s).second.context2 = (*s).second.contextLast = "";
201  }
202 
203  } // clearSummary()
204 
206  limits.wipe();
207  stats.erase(stats.begin(), stats.end()); //stats.clear();
208 
209  } // wipe()
210 
211  void ELstatistics::zero() { limits.zero(); } // zero()
212 
214  // Major changes 8/16/07 mf, including making this
215  // a static member function instead of a free function
216 
217  using std::ios; /* _base ? */
218  using std::left;
219  using std::right;
220  using std::setw;
221 
222  std::ostringstream s;
223  int n = 0;
224 
225  // ----- Summary part I:
226  //
227  bool ftnote(false);
228 
229  struct part3 {
230  long n, t;
231  part3() : n(0L), t(0L) { ; }
233 
234  std::set<std::string>::iterator gcEnd = groupedCategories.end();
235  std::set<std::string> gCats = groupedCategories; // TEMP FOR DEBUGGING SANITY
236  for (ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i) {
237  // If this is a grouped category, wait till later to output its stats
238  std::string cat = (*i).first.id;
239  if (groupedCategories.find(cat) != gcEnd) { // 8/16/07 mf
240  continue; // We will process these categories later
241  }
242 
243  // ----- Emit new process and part I header, if needed:
244  //
245  if (n == 0) {
246  s << "\n";
247  s << " type category sev module "
248  "subroutine count total\n"
249  << " ---- -------------------- -- ---------------- "
250  "---------------- ----- -----\n";
251  }
252  // ----- Emit detailed message information:
253  //
254  s << right << std::setw(5) << ++n << ' ' << left << std::setw(20) << (*i).first.id.substr(0, 20) << ' ' << left
255  << std::setw(2) << (*i).first.severity.getSymbol() << ' ' << left << std::setw(16)
256  << (*i).first.module.substr(0, 16) << ' ' << left << std::setw(16) << (*i).first.subroutine.substr(0, 16)
257  << right << std::setw(7) << (*i).second.n << left << std::setw(1) << ((*i).second.ignoredFlag ? '*' : ' ')
258  << right << std::setw(8) << (*i).second.aggregateN << '\n';
259  ftnote = ftnote || (*i).second.ignoredFlag;
260 
261  // ----- Obtain information for Part III, below:
262  //
263  ELextendedID xid = (*i).first;
264  p3[xid.severity.getLevel()].n += (*i).second.n;
265  p3[xid.severity.getLevel()].t += (*i).second.aggregateN;
266  } // for i
267 
268  // ----- Part Ia: The grouped categories
269  for (std::set<std::string>::iterator g = groupedCategories.begin(); g != gcEnd; ++g) {
270  int groupTotal = 0;
271  int groupAggregateN = 0;
273  bool groupIgnored = true;
274  for (ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i) {
275  if ((*i).first.id == *g) {
276  if (groupTotal == 0)
277  severityLevel = (*i).first.severity;
278  groupIgnored &= (*i).second.ignoredFlag;
279  groupAggregateN += (*i).second.aggregateN;
280  ++groupTotal;
281  }
282  } // for i
283  if (groupTotal > 0) {
284  // ----- Emit detailed message information:
285  //
286  s << right << std::setw(5) << ++n << ' ' << left << std::setw(20) << (*g).substr(0, 20) << ' ' << left
287  << std::setw(2) << severityLevel.getSymbol() << ' ' << left << std::setw(16) << " <Any Module> " << ' '
288  << left << std::setw(16) << "<Any Function>" << right << std::setw(7) << groupTotal << left << std::setw(1)
289  << (groupIgnored ? '*' : ' ') << right << std::setw(8) << groupAggregateN << '\n';
290  ftnote = ftnote || groupIgnored;
291 
292  // ----- Obtain information for Part III, below:
293  //
294  int lev = severityLevel.getLevel();
295  p3[lev].n += groupTotal;
296  p3[lev].t += groupAggregateN;
297  } // end if groupTotal>0
298  } // for g
299 
300  // ----- Provide footnote to part I, if needed:
301  //
302  if (ftnote)
303  s << "\n* Some occurrences of this message"
304  " were suppressed in all logs, due to limits.\n";
305 
306  // ----- Summary part II:
307  //
308  n = 0;
309  for (ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i) {
310  std::string cat = (*i).first.id;
311  if (groupedCategories.find(cat) != gcEnd) { // 8/16/07 mf
312  continue; // We will process these categories later
313  }
314  if (n == 0) {
315  s << '\n'
316  << " type category Examples: "
317  "run/evt run/evt run/evt\n"
318  << " ---- -------------------- ----"
319  "------------ ---------------- ----------------\n";
320  }
321  s << right << std::setw(5) << ++n << ' ' << left << std::setw(20) << (*i).first.id.c_str() << ' ' << left
322  << std::setw(16) << (*i).second.context1.c_str() << ' ' << left << std::setw(16)
323  << (*i).second.context2.c_str() << ' ' << (*i).second.contextLast.c_str() << '\n';
324  } // for
325 
326  // ----- Summary part III:
327  //
328  s << "\nSeverity # Occurrences Total Occurrences\n"
329  << "-------- ------------- -----------------\n";
330  for (int k = 0; k < ELseverityLevel::nLevels; ++k) {
331  if (p3[k].n != 0 || p3[k].t != 0) {
332  s << left << std::setw(8) << ELseverityLevel(ELseverityLevel::ELsev_(k)).getName().c_str() << right
333  << std::setw(17) << p3[k].n << right << std::setw(20) << p3[k].t << '\n';
334  }
335  } // for
336 
337  return s.str();
338 
339  } // formSummary()
340 
341  void ELstatistics::summary(std::ostream& os, const ELstring& title) {
342  os << title << std::endl << formSummary(stats) << std::flush;
343  updatedStats = false;
344 
345  } // summary()
346 
347  void ELstatistics::summary(unsigned long overfullWaitCount) {
348  termStream << "\n=============================================\n\n"
349  << "MessageLogger Summary" << std::endl
350  << formSummary(stats) << std::endl
351  << "dropped waiting message count " << overfullWaitCount << std::endl
352  << std::flush;
353  updatedStats = false;
354 
355  } // summary()
356 
358 
359  std::map<ELextendedID, StatsCount> ELstatistics::statisticsMap() const {
360  return std::map<ELextendedID, StatsCount>(stats);
361  }
362 
363  // 6/19/08 mf
364  void ELstatistics::summaryForJobReport(std::map<std::string, double>& sm) {
365  struct part3 {
366  long n, t;
367  part3() : n(0L), t(0L) { ; }
369 
370  std::set<std::string>::iterator gcEnd = groupedCategories.end();
371  std::set<std::string> gCats = groupedCategories; // TEMP FOR DEBUGGING SANITY
372 
373  // ----- Part I: The ungrouped categories
374  for (ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i) {
375  // If this is a grouped category, wait till later to output its stats
376  std::string cat = (*i).first.id;
377  if (groupedCategories.find(cat) != gcEnd) {
378  continue; // We will process these categories later
379  }
380 
381  // ----- Emit detailed message information:
382  //
383  std::ostringstream s;
384  s << "Category_";
385  std::string sevSymbol = (*i).first.severity.getSymbol();
386  if (sevSymbol[0] == '-')
387  sevSymbol = sevSymbol.substr(1);
388  s << sevSymbol << "_" << (*i).first.id;
389  int n = (*i).second.aggregateN;
390  std::string catstr = s.str();
391  if (sm.find(catstr) != sm.end()) {
392  sm[catstr] += n;
393  } else {
394  sm[catstr] = n;
395  }
396  // ----- Obtain information for Part III, below:
397  //
398  ELextendedID xid = (*i).first;
399  p3[xid.severity.getLevel()].n += (*i).second.n;
400  p3[xid.severity.getLevel()].t += (*i).second.aggregateN;
401  } // for i
402 
403  // ----- Part Ia: The grouped categories
404  for (std::set<std::string>::iterator g = groupedCategories.begin(); g != gcEnd; ++g) {
405  int groupTotal = 0;
406  int groupAggregateN = 0;
408  for (ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i) {
409  if ((*i).first.id == *g) {
410  if (groupTotal == 0)
411  severityLevel = (*i).first.severity;
412  groupAggregateN += (*i).second.aggregateN;
413  ++groupTotal;
414  }
415  } // for i
416  if (groupTotal > 0) {
417  // ----- Emit detailed message information:
418  //
419  std::ostringstream s;
420  s << "Category_";
421  std::string sevSymbol = severityLevel.getSymbol();
422  if (sevSymbol[0] == '-')
423  sevSymbol = sevSymbol.substr(1);
424  s << sevSymbol << "_" << *g;
425  int n = groupAggregateN;
426  std::string catstr = s.str();
427  if (sm.find(catstr) != sm.end()) {
428  sm[catstr] += n;
429  } else {
430  sm[catstr] = n;
431  }
432 
433  // ----- Obtain information for Part III, below:
434  //
435  int lev = severityLevel.getLevel();
436  p3[lev].n += groupTotal;
437  p3[lev].t += groupAggregateN;
438  } // end if groupTotal>0
439  } // for g
440 
441  // part II (sample event numbers) does not exist for the job report.
442 
443  // ----- Summary part III:
444  //
445  for (int k = 0; k < ELseverityLevel::nLevels; ++k) {
446  //if ( p3[k].t != 0 ) {
447  if (true) {
448  std::string sevName;
450  if (sevName == "Severe")
451  sevName = "System";
452  if (sevName == "Success")
453  sevName = "Debug";
454  sevName = std::string("Log") + sevName;
455  sevName = dualLogName(sevName);
456  if (sevName != "UnusedSeverity") {
457  sm[sevName] = p3[k].t;
458  }
459  }
460  } // for k
461 
462  } // summaryForJobReport()
463 
465  if (s == "LogDebug")
466  return "LogDebug_LogTrace";
467  if (s == "LogInfo")
468  return "LogInfo_LogVerbatim";
469  if (s == "LogWarning")
470  return "LogWarnng_LogPrint";
471  if (s == "LogError")
472  return "LogError_LogProblem";
473  if (s == "LogSystem")
474  return "LogSystem_LogAbsolute";
475  return "UnusedSeverity";
476  }
477 
478  std::set<std::string> ELstatistics::groupedCategories; // 8/16/07 mf
479 
481 
482  } // end of namespace service
483 } // end of namespace edm
static std::set< std::string > groupedCategories
Definition: ELstatistics.h:103
static std::string summarizeContext(const std::string &c)
ELseverityLevel severity
Definition: ELextendedID.h:29
std::unordered_set< std::string > ignoreThese
std::map< ELextendedID, StatsCount > statisticsMap() const
std::string dualLogName(std::string const &s)
virtual bool thisShouldBeIgnored(const ELstring &s) const
std::ostream & termStream
Definition: ELstatistics.h:99
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
static ELstring formSummary(ELmap_stats &stats)
const ELstring getSymbol() const
void summary(unsigned long overfullWaitCount)
const ELextendedID & xid() const
Definition: ErrorObj.cc:133
def cat(path)
Definition: eostools.py:401
const ELstring getName() const
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
static void noteGroupedCategory(std::string const &cat)
std::unordered_set< std::string > respondToThese
bool reactedTo() const
Definition: ErrorObj.cc:137
bool log(const edm::ErrorObj &msg) override
tuple msg
Definition: mps_check.py:285
HLT enums.
void summaryForJobReport(std::map< std::string, double > &sm)
std::string ELstring
Definition: ELstring.h:21
ELstring context() const
Definition: ErrorObj.cc:140
double p3[4]
Definition: TauolaWrapper.h:91
std::map< ELextendedID, StatsCount > ELmap_stats
Definition: ELmap.h:88