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