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 
27 
29 
31 
32 #include <iostream>
33 #include <iomanip>
34 #include <sstream>
35 #include <ios>
36 #include <cassert>
37 
38 // Possible Traces:
39 // #define ELstatisticsCONSTRUCTOR_TRACE
40 // #define ELstatsLOG_TRACE
41 
42 
43 namespace edm {
44 namespace service {
45 
46 
47 
48 // ----------------------------------------------------------------------
49 // Constructors
50 // ----------------------------------------------------------------------
51 
52 
54 : ELdestination ( )
55 , tableLimit ( -1 )
56 , stats ( )
57 , updatedStats ( false )
58 , termStream ( std::cerr )
59 , printAtTermination( true )
60 {
61 
62  #ifdef ELstatisticsCONSTRUCTOR_TRACE
63  std::cerr << "Constructor for ELstatistics()\n";
64  #endif
65 
66 } // ELstatistics()
67 
68 
69 ELstatistics::ELstatistics( std::ostream & osp )
70 : ELdestination ( )
71 , tableLimit ( -1 )
72 , stats ( )
73 , updatedStats ( false )
74 , termStream ( osp )
76 {
77 
78  #ifdef ELstatisticsCONSTRUCTOR_TRACE
79  std::cerr << "Constructor for ELstatistics(osp)\n";
80  #endif
81 
82 } // ELstatistics()
83 
84 
85 ELstatistics::ELstatistics( int spaceLimit )
86 : ELdestination ( )
87 , tableLimit ( spaceLimit )
88 , stats ( )
89 , updatedStats ( false )
90 , termStream ( std::cerr )
92 {
93 
94  #ifdef ELstatisticsCONSTRUCTOR_TRACE
95  std::cerr << "Constructor for ELstatistics(spaceLimit)\n";
96  #endif
97 
98 } // ELstatistics()
99 
100 
101 ELstatistics::ELstatistics( int spaceLimit, std::ostream & osp )
102 : ELdestination ( )
103 , tableLimit ( spaceLimit )
104 , stats ( )
105 , updatedStats ( false )
106 , termStream ( osp )
108 {
109 
110  #ifdef ELstatisticsCONSTRUCTOR_TRACE
111  std::cerr << "Constructor for ELstatistics(spaceLimit,osp)\n";
112  #endif
113 
114 } // ELstatistics()
115 
116 
118 : ELdestination ( )
119 , tableLimit ( orig.tableLimit )
120 , stats ( orig.stats )
121 , updatedStats ( orig.updatedStats )
122 , termStream ( orig.termStream )
124 {
125 
126  #ifdef ELstatisticsCONSTRUCTOR_TRACE
127  std::cerr << "Copy constructor for ELstatistics()\n";
128  #endif
129 
133  ignoreThese = orig.ignoreThese;
134 
135 } // ELstatistics()
136 
137 
139 
140  #ifdef ELstatisticsCONSTRUCTOR_TRACE
141  std::cerr << "Destructor for ELstatistics\n";
142  #endif
143 
145  summary( termStream, "Termination Summary" );
146 
147 } // ~ELstatistics()
148 
149 
150 // ----------------------------------------------------------------------
151 // Methods invoked by the ELadministrator
152 // ----------------------------------------------------------------------
153 
155  {
156  if ( c.substr (0,4) != "Run:" ) return c;
157  std::istringstream is (c);
158  std::string runWord;
159  int run;
160  is >> runWord >> run;
161  if (!is) return c;
162  if (runWord != "Run:") return c;
163  std::string eventWord;
164  int event;
165  is >> eventWord >> event;
166  if (!is) return c;
167  if (eventWord != "Event:") return c;
168  std::ostringstream os;
169  os << run << "/" << event;
170  return os.str();
171  }
172 
173 
175 
176  #ifdef ELstatsLOG_TRACE
177  std::cerr << " =:=:=: Log to an ELstatistics\n";
178  #endif
179 
180  // See if this message is to be counted.
181 
182  if ( msg.xid().severity < threshold ) return false;
183  if ( thisShouldBeIgnored(msg.xid().module) ) return false;
184 
185  // Account for this message, making a new table entry if needed:
186  //
187  ELmap_stats::iterator s = stats.find( msg.xid() );
188  if ( s == stats.end() ) {
189  if ( tableLimit < 0 || static_cast<int>(stats.size()) < tableLimit ) {
190  stats[msg.xid()] = StatsCount();
191  s = stats.find( msg.xid() );
192  }
193  }
194  #ifdef ELstatsLOG_TRACE
195  std::cerr << " =:=:=: Message accounted for in stats \n";
196  #endif
197  if ( s != stats.end() ) {
198  (*s).second.add( summarizeContext(msg.context()), msg.reactedTo() );
199 
200  updatedStats = true;
201  #ifdef ELstatsLOG_TRACE
202  std::cerr << " =:=:=: Updated stats \n";
203  #endif
204  }
205 
206 
207  // For the purposes of telling whether any log destination has reacted
208  // to the message, the statistics destination does not count:
209  //
210 
211  #ifdef ELstatsLOG_TRACE
212  std::cerr << " =:=:=: log(msg) done (stats) \n";
213  #endif
214 
215  return false;
216 
217 
218 } // log()
219 
220 
222 
223  limits.zero();
224  ELmap_stats::iterator s;
225  for ( s = stats.begin(); s != stats.end(); ++s ) {
226  (*s).second.n = 0;
227  (*s).second.context1 = (*s).second.context2 = (*s).second.contextLast = "";
228  }
229 
230 } // clearSummary()
231 
232 
234 
235  limits.wipe();
236  stats.erase( stats.begin(), stats.end() ); //stats.clear();
237 
238 } // wipe()
239 
240 
242 
243  limits.zero();
244 
245 } // zero()
246 
247 
249  // Major changes 8/16/07 mf, including making this
250  // a static member function instead of a free function
251 
252  using std::ios; /* _base ? */
253  using std::setw;
254  using std::right;
255  using std::left;
256 
257  std::ostringstream s;
258  int n = 0;
259 
260  // ----- Summary part I:
261  //
262  bool ftnote( false );
263 
264  struct part3 {
265  long n, t;
266  part3() : n(0L), t(0L) { ; }
268 
269  std::set<std::string>::iterator gcEnd = groupedCategories.end();
270  std::set<std::string> gCats = groupedCategories; // TEMP FOR DEBUGGING SANITY
271  for ( ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i ) {
272 
273  // If this is a grouped category, wait till later to output its stats
274  std::string cat = (*i).first.id;
275  if ( groupedCategories.find(cat) != gcEnd )
276  { // 8/16/07 mf
277  continue; // We will process these categories later
278  }
279 
280  // ----- Emit new process and part I header, if needed:
281  //
282  if ( n == 0 ) {
283  s << "\n";
284  s << " type category sev module "
285  "subroutine count total\n"
286  << " ---- -------------------- -- ---------------- "
287  "---------------- ----- -----\n"
288  ;
289  }
290  // ----- Emit detailed message information:
291  //
292  s << right << std::setw( 5) << ++n << ' '
293  << left << std::setw(20) << (*i).first.id.substr(0,20) << ' '
294  << left << std::setw( 2) << (*i).first.severity.getSymbol() << ' '
295  << left << std::setw(16) << (*i).first.module.substr(0,16) << ' '
296  << left << std::setw(16) << (*i).first.subroutine.substr(0,16)
297  << right << std::setw( 7) << (*i).second.n
298  << left << std::setw( 1) << ( (*i).second.ignoredFlag ? '*' : ' ' )
299  << right << std::setw( 8) << (*i).second.aggregateN << '\n'
300  ;
301  ftnote = ftnote || (*i).second.ignoredFlag;
302 
303  // ----- Obtain information for Part III, below:
304  //
305  ELextendedID xid = (*i).first;
306  p3[xid.severity.getLevel()].n += (*i).second.n;
307  p3[xid.severity.getLevel()].t += (*i).second.aggregateN;
308  } // for i
309 
310  // ----- Part Ia: The grouped categories
311  for ( std::set<std::string>::iterator g = groupedCategories.begin(); g != gcEnd; ++g ) {
312  int groupTotal = 0;
313  int groupAggregateN = 0;
315  bool groupIgnored = true;
316  for ( ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i ) {
317  if ( (*i).first.id == *g ) {
318  if (groupTotal==0) severityLevel = (*i).first.severity;
319  groupIgnored &= (*i).second.ignoredFlag;
320  groupAggregateN += (*i).second.aggregateN;
321  ++groupTotal;
322  }
323  } // for i
324  if (groupTotal > 0) {
325  // ----- Emit detailed message information:
326  //
327  s << right << std::setw( 5) << ++n << ' '
328  << left << std::setw(20) << (*g).substr(0,20) << ' '
329  << left << std::setw( 2) << severityLevel.getSymbol() << ' '
330  << left << std::setw(16) << " <Any Module> " << ' '
331  << left << std::setw(16) << "<Any Function>"
332  << right << std::setw( 7) << groupTotal
333  << left << std::setw( 1) << ( groupIgnored ? '*' : ' ' )
334  << right << std::setw( 8) << groupAggregateN << '\n'
335  ;
336  ftnote = ftnote || groupIgnored;
337 
338  // ----- Obtain information for Part III, below:
339  //
340  int lev = severityLevel.getLevel();
341  p3[lev].n += groupTotal;
342  p3[lev].t += groupAggregateN;
343  } // end if groupTotal>0
344  } // for g
345 
346  // ----- Provide footnote to part I, if needed:
347  //
348  if ( ftnote )
349  s << "\n* Some occurrences of this message"
350  " were suppressed in all logs, due to limits.\n"
351  ;
352 
353  // ----- Summary part II:
354  //
355  n = 0;
356  for ( ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i ) {
357  std::string cat = (*i).first.id;
358  if ( groupedCategories.find(cat) != gcEnd )
359  { // 8/16/07 mf
360  continue; // We will process these categories later
361  }
362  if ( n == 0 ) {
363  s << '\n'
364  << " type category Examples: "
365  "run/evt run/evt run/evt\n"
366  << " ---- -------------------- ----"
367  "------------ ---------------- ----------------\n"
368  ;
369  }
370  s << right << std::setw( 5) << ++n << ' '
371  << left << std::setw(20) << (*i).first.id.c_str() << ' '
372  << left << std::setw(16) << (*i).second.context1.c_str() << ' '
373  << left << std::setw(16) << (*i).second.context2.c_str() << ' '
374  << (*i).second.contextLast.c_str() << '\n'
375  ;
376  } // for
377 
378  // ----- Summary part III:
379  //
380  s << "\nSeverity # Occurrences Total Occurrences\n"
381  << "-------- ------------- -----------------\n";
382  for ( int k = 0; k < ELseverityLevel::nLevels; ++k ) {
383  if ( p3[k].n != 0 || p3[k].t != 0 ) {
384  s << left << std::setw( 8) << ELseverityLevel( ELseverityLevel::ELsev_(k) ).getName().c_str()
385  << right << std::setw(17) << p3[k].n
386  << right << std::setw(20) << p3[k].t
387  << '\n'
388  ;
389  }
390  } // for
391 
392  return s.str();
393 
394 } // formSummary()
395 
396 
397 void ELstatistics::summary( std::ostream & os, const ELstring & title ) {
398 
399  os << title << std::endl << formSummary(stats) << std::flush;
400  updatedStats = false;
401 
402 } // summary()
403 
404 void ELstatistics::summary(unsigned long overfullWaitCount ) {
405 
406  termStream << "\n=============================================\n\n"
407  << "MessageLogger Summary" << std::endl
408  << formSummary(stats) <<std::endl
409  << "dropped waiting message count "<<overfullWaitCount
410  << std::endl << std::flush;
411  updatedStats = false;
412 
413 } // summary()
414 
416 
417 std::map<ELextendedID , StatsCount> ELstatistics::statisticsMap() const {
418  return std::map<ELextendedID , StatsCount> ( stats );
419 }
420 
421 
422  // 6/19/08 mf
423 void ELstatistics::summaryForJobReport (std::map<std::string, double> & sm) {
424 
425  struct part3 {
426  long n, t;
427  part3() : n(0L), t(0L) { ; }
429 
430  std::set<std::string>::iterator gcEnd = groupedCategories.end();
431  std::set<std::string> gCats = groupedCategories; // TEMP FOR DEBUGGING SANITY
432 
433  // ----- Part I: The ungrouped categories
434  for ( ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i ) {
435 
436  // If this is a grouped category, wait till later to output its stats
437  std::string cat = (*i).first.id;
438  if ( groupedCategories.find(cat) != gcEnd )
439  {
440  continue; // We will process these categories later
441  }
442 
443  // ----- Emit detailed message information:
444  //
445  std::ostringstream s;
446  s << "Category_";
447  std::string sevSymbol = (*i).first.severity.getSymbol();
448  if ( sevSymbol[0] == '-' ) sevSymbol = sevSymbol.substr(1);
449  s << sevSymbol << "_" << (*i).first.id;
450  int n = (*i).second.aggregateN;
451  std::string catstr = s.str();
452  if (sm.find(catstr) != sm.end()) {
453  sm[catstr] += n;
454  } else {
455  sm[catstr] = n;
456  }
457  // ----- Obtain information for Part III, below:
458  //
459  ELextendedID xid = (*i).first;
460  p3[xid.severity.getLevel()].n += (*i).second.n;
461  p3[xid.severity.getLevel()].t += (*i).second.aggregateN;
462  } // for i
463 
464  // ----- Part Ia: The grouped categories
465  for ( std::set<std::string>::iterator g = groupedCategories.begin(); g != gcEnd; ++g ) {
466  int groupTotal = 0;
467  int groupAggregateN = 0;
469  for ( ELmap_stats::const_iterator i = stats.begin(); i != stats.end(); ++i ) {
470  if ( (*i).first.id == *g ) {
471  if (groupTotal==0) severityLevel = (*i).first.severity;
472  groupAggregateN += (*i).second.aggregateN;
473  ++groupTotal;
474  }
475  } // for i
476  if (groupTotal > 0) {
477  // ----- Emit detailed message information:
478  //
479  std::ostringstream s;
480  s << "Category_";
481  std::string sevSymbol = severityLevel.getSymbol();
482  if ( sevSymbol[0] == '-' ) sevSymbol = sevSymbol.substr(1);
483  s << sevSymbol << "_" << *g;
484  int n = groupAggregateN;
485  std::string catstr = s.str();
486  if (sm.find(catstr) != sm.end()) {
487  sm[catstr] += n;
488  } else {
489  sm[catstr] = n;
490  }
491 
492  // ----- Obtain information for Part III, below:
493  //
494  int lev = severityLevel.getLevel();
495  p3[lev].n += groupTotal;
496  p3[lev].t += groupAggregateN;
497  } // end if groupTotal>0
498  } // for g
499 
500  // part II (sample event numbers) does not exist for the job report.
501 
502  // ----- Summary part III:
503  //
504  for ( int k = 0; k < ELseverityLevel::nLevels; ++k ) {
505  //if ( p3[k].t != 0 ) {
506  if (true) {
507  std::string sevName;
509  if (sevName == "Severe") sevName = "System";
510  if (sevName == "Success") sevName = "Debug";
511  sevName = std::string("Log")+sevName;
512  sevName = dualLogName(sevName);
513  if (sevName != "UnusedSeverity") {
514  sm[sevName] = p3[k].t;
515  }
516  }
517  } // for k
518 
519 } // summaryForJobReport()
520 
522 {
523  if (s=="LogDebug") return "LogDebug_LogTrace";
524  if (s=="LogInfo") return "LogInfo_LogVerbatim";
525  if (s=="LogWarning") return "LogWarnng_LogPrint";
526  if (s=="LogError") return "LogError_LogProblem";
527  if (s=="LogSystem") return "LogSystem_LogAbsolute";
528  return "UnusedSeverity";
529 }
530 
531 std::set<std::string> ELstatistics::groupedCategories; // 8/16/07 mf
532 
534  groupedCategories.insert(cat);
535 }
536 
537 } // end of namespace service
538 } // end of namespace edm
static std::set< std::string > groupedCategories
Definition: ELstatistics.h:110
static std::string summarizeContext(const std::string &c)
ELseverityLevel severity
Definition: ELextendedID.h:35
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
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:148
def cat(path)
Definition: eostools.py:400
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
int k[5][pyjets_maxn]
bool reactedTo() const
Definition: ErrorObj.cc:152
bool log(const edm::ErrorObj &msg) override
tuple msg
Definition: mps_check.py:277
std::map< ELextendedID, StatsCount > ELmap_stats
Definition: ELmap.h:103
HLT enums.
void summaryForJobReport(std::map< std::string, double > &sm)
std::string ELstring
Definition: ELstring.h:26
ELstring context() const
Definition: ErrorObj.cc:155
double p3[4]
Definition: TauolaWrapper.h:91