CMS 3D CMS Logo

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