CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/FWCore/MessageService/src/ELadministrator.cc

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------
00002 //
00003 // ELadministrator.cc
00004 //
00005 // Methods of ELadministrator.
00006 //
00007 // History:
00008 //
00009 // 7/2/98  mf   Created
00010 // 7/6/98  mf   Added ELadministratorX knowledge
00011 // 6/16/99 jvr  Attaches a destination when an error is logged and
00012 //              no destinations are attached          $$ JV:1
00013 // 6/18/99 jvr/mf       Constructor for ELadministratorX uses explcitly
00014 //              constructed ELseverityLevels in its init list, rather
00015 //              than objectslike ELabort, which may not yet have
00016 //              been fully constructed.  Repairs a problem with ELcout.
00017 // 6/23/99  mf  Made emptyContextSUpplier static to this comp unit.
00018 // 12/20/99 mf  Added virtual destructor to ELemptyContextSupplier.
00019 // 2/29/00  mf  swapContextSupplier.
00020 // 4/05/00  mf  swapProcess.
00021 // 5/03/00  mf  When aborting, changed exit() to abort() so that dump
00022 //              will reflect true condition without unwinding things.
00023 // 6/6/00  web  Consolidated ELadministrator/X.
00024 // 6/7/00  web  Reflect consolidation of ELdestination/X.
00025 // 6/12/00 web  Attach cerr, rather than cout, in case of no previously-
00026 //              attached destination; using -> USING.
00027 // 3/6/00  mf   Attach taking name to id the destination, getELdestControl()
00028 // 3/14/01 mf   exitThreshold
00029 // 1/10/06 mf   finish()
00030 //
00031 // ---- CMS version
00032 //
00033 // 12/12/05 mf  change exit() to throw edm::exception
00034 //
00035 //-----------------------------------------------------------------------
00036 
00037 // Directory of methods:
00038 //----------------------
00039 
00040 // ELadministrator::setProcess( const ELstring & process )
00041 // ELadministrator::swapProcess( const ELstring & process )
00042 // ELadministrator::setContextSupplier( const ELcontextSupplier & supplier )
00043 // ELadministrator::getContextSupplier() const
00044 // ELadministrator::swapContextSupplier( ELcontextSupplier & supplier )
00045 // ELadministrator::setAbortThreshold( const ELseverityLevel & sev )
00046 // ELadministrator::setExitThreshold( const ELseverityLevel & sev )
00047 // ELadministrator::attach( const ELdestination & sink )
00048 // ELadministrator::attach( const ELdestination & sink, const ELstring & name )
00049 // ELadministrator::getELdestControl ( const ELstring & name,
00050 //                                      ELdestControl & theDestControl )
00051 // ELadministrator::checkSeverity()
00052 // ELadministrator::severityCount( const ELseverityLevel & sev ) const
00053 // ELadministrator::severityCount( const ELseverityLevel & from,
00054 //                                  const ELseverityLevel & to    ) const
00055 // ELadministrator::resetSeverityCount( const ELseverityLevel & sev )
00056 // ELadministrator::resetSeverityCount( const ELseverityLevel & from,
00057 //                                      const ELseverityLevel & to    )
00058 // ELadministrator::resetSeverityCount()
00059 // ELadministrator::setThresholds( const ELseverityLevel & sev )
00060 // ELadministrator::setLimits( const ELstring & id, int limit )
00061 // ELadministrator::setLimits( const ELseverityLevel & sev, int limit )
00062 // ELadministrator::setIntervals( const ELstring & id, int interval )
00063 // ELadministrator::setIntervals( const ELseverityLevel & sev, int interval )
00064 // ELadministrator::setTimespans( const ELstring & id, int seconds )
00065 // ELadministrator::setTimespans( const ELseverityLevel & sev, int seconds )
00066 // ELadministrator::wipe()
00067 // ELadministrator::finish()
00068 //
00069 // ELadministrator::process() const
00070 // ELadministrator::context() const
00071 // ELadministrator::abortThreshold() const
00072 // ELadministrator::exitThreshold() const
00073 // ELadministrator::sinks()
00074 // ELadministrator::highSeverity() const
00075 // ELadministrator::severityCounts( const int lev ) const
00076 // ELadministrator::finishMsg()
00077 // ELadministrator::clearMsg()
00078 //
00079 // class ELemptyContextSupplier : public ELcontextSupplier
00080 //
00081 // ----------------------------------------------------------------------
00082 
00083 
00084 #include "FWCore/MessageService/interface/ELadministrator.h"
00085 #include "FWCore/MessageService/interface/ELdestination.h"
00086 #include "FWCore/MessageService/interface/ELcontextSupplier.h"
00087 #include "FWCore/MessageService/interface/ELoutput.h"
00088 
00089 #include "FWCore/Utilities/interface/EDMException.h"
00090 
00091 #include <iostream>
00092 #include <sstream>
00093 #include <list>
00094 using std::cerr;
00095 
00096 
00097 namespace edm {
00098 namespace service {
00099 
00100 
00101 // Possible Traces:
00102 // #define ELadministratorCONSTRUCTOR_TRACE
00103 // #define ELadTRACE_FINISH
00104 
00105 
00106 // ----------------------------------------------------------------------
00107 // ELadministrator functionality:
00108 // ----------------------------------------------------------------------
00109 
00110 void ELadministrator::setProcess( const ELstring & process )  {
00111 
00112   process_ = process;
00113   #if 0
00114     std::cerr << "Administrator process set to \"" << process << "\"\n";
00115   #endif
00116 
00117 }  // setProcess()
00118 
00119 
00120 ELstring ELadministrator::swapProcess( const ELstring & process )  {
00121 
00122   ELstring temp = process_;
00123   process_ = process;
00124   return temp;
00125 
00126 } // swapProcess()
00127 
00128 
00129 void ELadministrator::setContextSupplier( const ELcontextSupplier & supplier )  {
00130 
00131   context_.reset(supplier.clone());
00132 
00133 }  // setContextSupplier()
00134 
00135 
00136 const ELcontextSupplier & ELadministrator::getContextSupplier() const  {
00137 
00138   return *(context_);
00139 
00140 }  // getContextSupplier()
00141 
00142 ELcontextSupplier & ELadministrator::swapContextSupplier
00143                                         (ELcontextSupplier & cs)  {
00144   ELcontextSupplier & save = *(context_);
00145   context_.reset(&cs);
00146   return save;
00147 } // swapContextSupplier
00148 
00149 
00150 void ELadministrator::setAbortThreshold( const ELseverityLevel & sev )  {
00151 
00152   abortThreshold_ = sev;
00153 
00154 }  // setAbortThreshold()
00155 
00156 void ELadministrator::setExitThreshold( const ELseverityLevel & sev )  {
00157 
00158   exitThreshold_ = sev;
00159 
00160 }  // setExitThreshold()
00161 
00162 ELdestControl ELadministrator::attach( const ELdestination & sink )  {
00163 
00164   boost::shared_ptr<ELdestination> dest(sink.clone());
00165   sinks().push_back( dest );
00166   return ELdestControl( dest );
00167 
00168 }  // attach()
00169 
00170 ELdestControl ELadministrator::attach(  const ELdestination & sink,
00171                                         const ELstring & name )     {
00172   boost::shared_ptr<ELdestination> dest(sink.clone());
00173   attachedDestinations[name] = dest;
00174   sinks().push_back( dest );
00175   return ELdestControl( dest );
00176 } // attach()
00177 
00178 
00179 bool ELadministrator::getELdestControl ( const ELstring & name,
00180                                          ELdestControl & theDestControl ) {
00181 
00182   if ( attachedDestinations.find(name) != attachedDestinations.end() ) {
00183     theDestControl = ELdestControl ( attachedDestinations[name] );
00184     return true;
00185   } else {
00186     return false;
00187   }
00188 
00189 } // getDestControl
00190 
00191 ELseverityLevel  ELadministrator::checkSeverity()  {
00192 
00193   const ELseverityLevel  retval( highSeverity_ );
00194   highSeverity_ = ELzeroSeverity;
00195   return retval;
00196 
00197 }  // checkSeverity()
00198 
00199 
00200 int ELadministrator::severityCount( const ELseverityLevel & sev ) const  {
00201 
00202   return severityCounts_[sev.getLevel()];
00203 
00204 }  // severityCount()
00205 
00206 
00207 int ELadministrator::severityCount(
00208   const ELseverityLevel & from,
00209   const ELseverityLevel & to
00210 )  const  {
00211 
00212   int k = from.getLevel();
00213   int sum = severityCounts_[k];
00214 
00215   while ( ++k <= to.getLevel() )
00216     sum += severityCounts_[k];
00217 
00218   return  sum;
00219 
00220 }  // severityCount()
00221 
00222 
00223 void ELadministrator::resetSeverityCount( const ELseverityLevel & sev )  {
00224 
00225   severityCounts_[sev.getLevel()] = 0;
00226 
00227 }  // resetSeverityCount()
00228 
00229 
00230 void ELadministrator::resetSeverityCount( const ELseverityLevel & from,
00231                                           const ELseverityLevel & to   )  {
00232 
00233   for ( int k = from.getLevel();  k <= to.getLevel();  ++k )
00234     severityCounts_[k] = 0;
00235 
00236 }  // resetSeverityCount()
00237 
00238 
00239 void ELadministrator::resetSeverityCount()  {
00240 
00241   resetSeverityCount( ELzeroSeverity, ELhighestSeverity );
00242 
00243 }  // resetSeverityCount()
00244 
00245 
00246 // ----------------------------------------------------------------------
00247 // Accessors:
00248 // ----------------------------------------------------------------------
00249 
00250 const ELstring & ELadministrator::process() const  { return process_; }
00251 
00252 
00253 ELcontextSupplier & ELadministrator::context() const  { return *context_; }
00254 
00255 
00256 const ELseverityLevel & ELadministrator::abortThreshold() const  {
00257   return abortThreshold_;
00258 }
00259 
00260 const ELseverityLevel & ELadministrator::exitThreshold() const  {
00261   return exitThreshold_;
00262 }
00263 
00264 std::list<boost::shared_ptr<ELdestination> > & ELadministrator::sinks()  { return sinks_; }
00265 
00266 
00267 const ELseverityLevel & ELadministrator::highSeverity() const  {
00268   return highSeverity_;
00269 }
00270 
00271 
00272 int ELadministrator::severityCounts( const int lev ) const  {
00273   return severityCounts_[lev];
00274 }
00275 
00276 
00277 // ----------------------------------------------------------------------
00278 // Message handling:
00279 // ----------------------------------------------------------------------
00280 
00281 static inline void msgexit(int s) {
00282   std::ostringstream os;
00283   os << "msgexit - MessageLogger requested to exit with status " << s;
00284   edm::Exception e(edm::errors::LogicError, os.str());
00285   throw e;
00286 }
00287 
00288 static inline void msgabort() {
00289   std::ostringstream os;
00290   os << "msgabort - MessageLogger requested to abort";
00291   edm::Exception e(edm::errors::LogicError, os.str());
00292   throw e;
00293 }
00294 
00295 static inline void possiblyAbortOrExit (int s, int a, int e) {
00296   if (s < a && s < e) return;
00297   if (a < e) {
00298     if ( s < e ) msgabort();
00299     msgexit(s);
00300   } else {
00301     if ( s < a ) msgexit(s);
00302     msgabort();
00303   }
00304 }
00305 
00306 void ELadministrator::finishMsg()  {
00307 
00308   if ( ! msgIsActive )
00309     return;
00310 
00311   int lev = msg.xid().severity.getLevel();
00312   ++ severityCounts_[lev];
00313   if ( lev > highSeverity_.getLevel() )
00314     highSeverity_ = msg.xid().severity;
00315 
00316   #ifdef ELadTRACE_FINISH
00317     std::cerr << "=:=:=: finshMsg() - lev = " << lev << "\n";
00318   #endif
00319 
00320   context_->editErrorObj( msg );
00321 
00322   #ifdef ELadTRACE_FINISH
00323     std::cerr << "=:=:=: finshMsg() returns from editErrorObj( msg ) \n";
00324   #endif
00325 
00326   std::list<boost::shared_ptr<ELdestination> >::iterator d;
00327   bool mrt;
00328   #ifdef ELadTRACE_FINISH
00329     int destCounter = 0;
00330   #endif
00331   if ( sinks().begin() == sinks().end() )  {                   // $$ JV:1
00332     std::cerr << "\nERROR LOGGED WITHOUT DESTINATION!\n";
00333     std::cerr << "Attaching destination \"cerr\" to ELadministrator by default\n\n";
00334     boost::shared_ptr<ELdestination> dest(new ELoutput(cerr));
00335     this->sinks().push_back(dest);
00336   }
00337   for ( d = sinks().begin();  d != sinks().end();  ++d )  {
00338     #ifdef ELadTRACE_FINISH
00339       std::cerr << "  =:=:=: log(msg) for a destination number "
00340            << ++destCounter << " called ... \n";
00341     #endif
00342     mrt = (*d)->log( msg );
00343     #ifdef ELadTRACE_FINISH
00344       std::cerr << "  =:=:=: log(msg) for a destination returned " << mrt << "\n";
00345     #endif
00346     if ( mrt )
00347       msg.setReactedTo(true);
00348   }
00349 
00350   msgIsActive = false;
00351 
00352   possiblyAbortOrExit ( lev,
00353                         abortThreshold().getLevel(),
00354                         exitThreshold().getLevel()   );         // $$ mf 3/17/04
00355 
00356 }  // finishMsg()
00357 
00358 
00359 void ELadministrator::clearMsg()  {
00360 
00361   msgIsActive = false;
00362   msg.clear();
00363 
00364 }  // clearMsg()
00365 
00366 
00367 // ----------------------------------------------------------------------
00368 // The following do the indicated action to all attached destinations:
00369 // ----------------------------------------------------------------------
00370 
00371 void ELadministrator::setThresholds( const ELseverityLevel & sev )  {
00372 
00373   std::list<boost::shared_ptr<ELdestination> >::iterator d;
00374   for ( d = sinks().begin();  d != sinks().end();  ++d )
00375     (*d)->threshold = sev;
00376 
00377 }  // setThresholds()
00378 
00379 
00380 void ELadministrator::setLimits( const ELstring & id, int limit )  {
00381 
00382   std::list<boost::shared_ptr<ELdestination> >::iterator d;
00383   for ( d = sinks().begin();  d != sinks().end();  ++d )
00384     (*d)->limits.setLimit( id, limit );
00385 
00386 }  // setLimits()
00387 
00388 
00389 void ELadministrator::setIntervals
00390                         ( const ELseverityLevel & sev, int interval )  {
00391 
00392   std::list<boost::shared_ptr<ELdestination> >::iterator d;
00393   for ( d = sinks().begin();  d != sinks().end();  ++d )
00394     (*d)->limits.setInterval( sev, interval );
00395 
00396 }  // setIntervals()
00397 
00398 void ELadministrator::setIntervals( const ELstring & id, int interval )  {
00399 
00400   std::list<boost::shared_ptr<ELdestination> >::iterator d;
00401   for ( d = sinks().begin();  d != sinks().end();  ++d )
00402     (*d)->limits.setInterval( id, interval );
00403 
00404 }  // setIntervals()
00405 
00406 
00407 void ELadministrator::setLimits( const ELseverityLevel & sev, int limit )  {
00408 
00409   std::list<boost::shared_ptr<ELdestination> >::iterator d;
00410   for ( d = sinks().begin();  d != sinks().end();  ++d )
00411     (*d)->limits.setLimit( sev, limit );
00412 
00413 }  // setLimits()
00414 
00415 
00416 void ELadministrator::setTimespans( const ELstring & id, int seconds )  {
00417 
00418   std::list<boost::shared_ptr<ELdestination> >::iterator d;
00419   for ( d = sinks().begin();  d != sinks().end();  ++d )
00420     (*d)->limits.setTimespan( id, seconds );
00421 
00422 }  // setTimespans()
00423 
00424 
00425 void ELadministrator::setTimespans( const ELseverityLevel & sev, int seconds )  {
00426 
00427   std::list<boost::shared_ptr<ELdestination> >::iterator d;
00428   for ( d = sinks().begin();  d != sinks().end();  ++d )
00429     (*d)->limits.setTimespan( sev, seconds );
00430 
00431 }  // setTimespans()
00432 
00433 
00434 void ELadministrator::wipe()  {
00435 
00436   std::list<boost::shared_ptr<ELdestination> >::iterator d;
00437   for ( d = sinks().begin();  d != sinks().end();  ++d )
00438     (*d)->limits.wipe();
00439 
00440 }  // wipe()
00441 
00442 void ELadministrator::finish()  {
00443 
00444   std::list<boost::shared_ptr<ELdestination> >::iterator d;
00445   for ( d = sinks().begin();  d != sinks().end();  ++d )
00446     (*d)->finish();
00447 
00448 }  // wipe()
00449 
00450 
00451 // ----------------------------------------------------------------------
00452 // ELemptyContextSupplier (dummy default ELcontextSupplier):
00453 // ----------------------------------------------------------------------
00454 
00455 class ELemptyContextSupplier : public ELcontextSupplier  {
00456 
00457 public:
00458 
00459   virtual
00460   ELemptyContextSupplier *
00461   clone() const  {
00462     return new ELemptyContextSupplier( *this );
00463   }
00464   virtual ELstring context()        const  {  return ""; }
00465   virtual ELstring summaryContext() const  {  return ""; }
00466   virtual ELstring fullContext()    const  {  return ""; }
00467 
00468   virtual ~ELemptyContextSupplier()  {}
00469 
00470 };  // ELemptyContextSupplier
00471 
00472 
00473 static ELemptyContextSupplier  emptyContext;
00474 
00475 
00476 // ----------------------------------------------------------------------
00477 // The Destructable Singleton pattern
00478 // (see "To Kill a Singleton," Vlissides, C++ Report):
00479 // ----------------------------------------------------------------------
00480 
00481 
00482 ELadministrator * ELadministrator::instance_ = 0;
00483 
00484 
00485 ELadministrator * ELadministrator::instance()  {
00486 
00487   static ELadminDestroyer destroyer_;
00488   // This deviates from Vlissides' pattern where destroyer_ was a static
00489   // instance in the ELadministrator class.  This construct should be
00490   // equivalent, but the original did not call the destructor under KCC.
00491 
00492   if ( !instance_ )  {
00493     instance_ = new ELadministrator;
00494     destroyer_.setELadmin( instance_ );
00495   }
00496   return instance_;
00497 
00498 }  // instance()
00499 
00500 
00501 ELadministrator::ELadministrator()
00502 : process_       ( ""                                                        )
00503 , context_       ( emptyContext.clone()                                      )
00504 , abortThreshold_( ELseverityLevel (ELseverityLevel::ELsev_abort)            )
00505 , exitThreshold_ ( ELseverityLevel (ELseverityLevel::ELsev_highestSeverity   )            )
00506 , sinks_         (                                                           )
00507 , highSeverity_  ( ELseverityLevel (ELseverityLevel::ELsev_zeroSeverity)     )
00508 , msg            ( ELseverityLevel (ELseverityLevel::ELsev_unspecified), ""  )
00509 , msgIsActive    ( false                                                     )
00510 {
00511 
00512   #ifdef ELadministratorCONSTRUCTOR_TRACE
00513     std::cerr << "ELadminstrator constructor\n";
00514   #endif
00515 
00516   for ( int lev = 0;  lev < ELseverityLevel::nLevels;  ++lev )
00517     severityCounts_[lev] = 0;
00518 
00519 }  // ELadministrator()
00520 
00521 
00522 ELadminDestroyer::ELadminDestroyer( ELadministrator * ad )  : admin_( ad )  {}
00523 
00524 
00525 ELadminDestroyer::~ELadminDestroyer()  {
00526 
00527   #ifdef ELadministratorCONSTRUCTOR_TRACE
00528     std::cerr << "~ELadminDestroyer: Deleting admin_\n";
00529   #endif
00530 
00531   delete admin_;
00532 
00533 }  // ~ELadminDestroyer()
00534 
00535 
00536 void ELadminDestroyer::setELadmin( ELadministrator * ad )  { admin_ = ad; }
00537 
00538 
00539 //-*****************************
00540 // The ELadminstrator destructor
00541 //-*****************************
00542 
00543 ELadministrator::~ELadministrator()  {
00544 
00545   #ifdef ELadministratorCONSTRUCTOR_TRACE
00546     std::cerr << "ELadministrator Destructor\n";
00547   #endif
00548 
00549   finishMsg();
00550 
00551   sinks().clear();
00552 
00553 }  // ~ELadministrator()
00554 
00555 
00556 
00557 // ----------------------------------------------------------------------
00558 
00559 
00560 } // end of namespace service  
00561 } // end of namespace edm