CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/FWCore/MessageService/src/ErrorLog.cc

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------
00002 //
00003 // ErrorLog.cc
00004 //
00005 // Created 7/7/98 mf
00006 // 5/2/99  web  Added non-default constructor.
00007 // 6/16/99 jvr  Attaches a destination when an ErrorObj is logged and no
00008 //              destinations are attached                       $$ jvr
00009 // 6/6/00  web  Reflect consolidation of ELadministrator/X; consolidate
00010 //              ErrorLog/X
00011 // 6/12/00 web  Attach cerr, rather than cout, in case of no previously-
00012 //              attached destination
00013 // 6/14/00 web  Append missing quote on conditional output
00014 // 3/13/01 mf   hexTrigger and related global methods
00015 // 3/13/01 mf   setDiscardThreshold(), and discardThreshold mechanism
00016 // 3/14/01 web  g/setfill(0)/s//setfill('0')/g; move #include <string>
00017 // 3/14/01 web  Insert missing initializers in constructor
00018 // 5/7/01  mf   operator<< (const char[])
00019 // 6/7/01  mf   operator()(ErrorObj&) should have been doing level bookkeeping
00020 //              and abort checking; inserted this code
00021 // 11/15/01 mf  static_cast to unsigned int and long in comparisons in
00022 //              operator<<( ErrorLog & e, unsigned int n) and long, and
00023 //              also rwriting 0xFFFFFFFF as 0xFFFFFFFFL when comparing to a
00024 //              long.  THese cure warnings when -Wall -pedantic are turned on.
00025 // 3/06/01 mf   getELdestControl() forwards to *a
00026 // 12/3/02 mf   discardVerbosityLevel, and items related to operator()(int)
00027 // 6/23/03 mf   moduleName() and subroutineName()
00028 // 3/17/04 mf   spaces after ints.
00029 // 3/17/04 mf   exit threshold
00030 //
00031 // --- CMS
00032 //
00033 // 12/12/05 mf  replace exit() with throw
00034 //
00035 // ----------------------------------------------------------------------
00036 
00037 
00038 #include "FWCore/MessageService/interface/ErrorLog.h"
00039 #include "FWCore/MessageService/interface/ELadministrator.h"
00040 #include "FWCore/MessageService/interface/ELdestination.h"
00041 #include "FWCore/MessageService/interface/ELoutput.h"
00042 #include "FWCore/MessageService/interface/ELrecv.h"
00043 #include "FWCore/MessageService/interface/ELcontextSupplier.h"
00044 
00045 #include "FWCore/Utilities/interface/EDMException.h"
00046 
00047 #include <iostream>
00048 #include <iomanip>
00049 
00050 // Possible Traces:
00051 // #define ErrorLogCONSTRUCTOR_TRACE
00052 // #define ErrorLogOUTPUT_TRACE
00053 // #define ErrorLogENDMSG_TRACE
00054 // #define ErrorLogEMIT_TRACE
00055 
00056 #ifdef ErrorLog_EMIT_TRACE
00057   #include <string>
00058 #endif
00059 
00060 namespace edm {
00061 namespace service {
00062 
00063 
00064 
00065 // ----------------------------------------------------------------------
00066 // ErrorLog:
00067 // ----------------------------------------------------------------------
00068 
00069 ErrorLog::ErrorLog()
00070 : a( ELadministrator::instance() )
00071 , subroutine( "" )
00072 , module( "" )
00073 , hexTrigger(-1)
00074 , spaceAfterInt(false)
00075 , discardThreshold (ELzeroSeverity)
00076 , discarding (false)
00077 , debugVerbosityLevel(0)
00078 , debugSeverityLevel(ELinfo)
00079 , debugMessageId ("DEBUG")
00080 {
00081 
00082   #ifdef ErrorLogCONSTRUCTOR_TRACE
00083     std::cout << "Constructor for ErrorLog\n";
00084   #endif
00085 
00086 }  // ErrorLog()
00087 
00088 ErrorLog::ErrorLog( const ELstring & pkgName )
00089 : a( ELadministrator::instance() )
00090 , subroutine( "" )
00091 , module( pkgName )
00092 , hexTrigger(-1)
00093 , spaceAfterInt(false)
00094 , discardThreshold (ELzeroSeverity)
00095 , discarding (false)
00096 , debugVerbosityLevel(0)
00097 , debugSeverityLevel(ELinfo)
00098 , debugMessageId ("DEBUG")
00099 {
00100 
00101   #ifdef ErrorLogCONSTRUCTOR_TRACE
00102     std::cout << "Constructor for ErrorLog (with pkgName = " << pkgName << ")\n";
00103   #endif
00104 
00105 }  // ErrorLog()
00106 
00107 
00108 ErrorLog::~ErrorLog()  {
00109 
00110   #ifdef ErrorLogCONSTRUCTOR_TRACE
00111     std::cout << "Destructor for ErrorLog\n";
00112   #endif
00113 
00114 }  // ~ErrorLog()
00115 
00116 ErrorLog & ErrorLog::operator() (
00117   const ELseverityLevel & sev
00118 , const ELstring & id )
00119 {
00120 
00121   if ( sev < discardThreshold ) {
00122     discarding = true;
00123     return *this;
00124   }
00125 
00126   discarding = false;
00127 
00128   #ifdef ErrorLogENDMSG_TRACE
00129     std::cout << "=:=:=: precautionary endmsg ( "
00130               << sev.getName() << ", " << id << ")\n";
00131   #endif
00132 
00133   endmsg();  // precautionary
00134 
00135   // -----  form ErrorObj for this new message:
00136   //
00137   a->msgIsActive = true;
00138   a->msg.set          ( sev, id );
00139   a->msg.setProcess   ( a->process() );
00140   a->msg.setModule    ( module );
00141   a->msg.setSubroutine( subroutine );
00142   a->msg.setReactedTo ( false );
00143 
00144   return  *this;
00145 
00146 }  // operator()( sev, id )
00147 
00148 
00149 void ErrorLog::setSubroutine( const ELstring & subName )  {
00150 
00151   subroutine = subName;
00152 
00153 }  // setSubroutine()
00154 
00155 static inline void msgexit(int s) {
00156   std::ostringstream os;
00157   os << "msgexit - MessageLogger Log requested to exit with status " << s;
00158   edm::Exception e(edm::errors::LogicError, os.str());
00159   throw e;
00160 }
00161 
00162 static inline void msgabort() {
00163   std::ostringstream os;
00164   os << "msgabort - MessageLogger Log requested to abort";
00165   edm::Exception e(edm::errors::LogicError, os.str());
00166   throw e;
00167 }
00168 
00169 static inline void possiblyAbOrEx (int s, int a, int e) {
00170   if (s < a && s < e) return;
00171   if (a < e) {
00172     if ( s < e ) msgabort();
00173     msgexit(s);
00174   } else {
00175     if ( s < a ) msgexit(s);
00176     msgabort();
00177   }
00178 }
00179 
00180 ErrorLog & ErrorLog::operator()( edm::ErrorObj & msg )  {
00181 
00182   #ifdef ErrorLogENDMSG_TRACE
00183     std::cout << "=:=:=: precautionary endmsg called from operator() (msg) \n";
00184   #endif
00185 
00186   endmsg();  // precautionary
00187 
00188   // -----  will we need to poke/restore info into the message?
00189   //
00190   bool updateProcess   ( msg.xid().process   .length() == 0 );
00191   bool updateModule    ( msg.xid().module    .length() == 0 );
00192   bool updateSubroutine( msg.xid().subroutine.length() == 0 );
00193 
00194   // -----  poke, if needed:
00195   //
00196   if ( updateProcess    )  msg.setProcess   ( a->process() );
00197   if ( updateModule     )  msg.setModule    ( module );
00198   if ( updateSubroutine )  msg.setSubroutine( subroutine );
00199 
00200   // severity level statistics keeping:                 // $$ mf 6/7/01
00201   int lev = msg.xid().severity.getLevel();
00202   ++ a->severityCounts_[lev];
00203   if ( lev > a->highSeverity_.getLevel() )
00204     a->highSeverity_ = msg.xid().severity;
00205 
00206   a->context_->editErrorObj( msg );
00207 
00208   // -----  send the message to each destination:
00209   //
00210   if (a->sinks().begin() == a->sinks().end())  {
00211     std::cerr << "\nERROR LOGGED WITHOUT DESTINATION!\n";
00212     std::cerr << "Attaching destination \"cerr\" to ELadministrator by default\n"
00213               << std::endl;
00214     a->attach(ELoutput(std::cerr));
00215   }
00216   std::list<boost::shared_ptr<ELdestination> >::iterator d;
00217   for ( d = a->sinks().begin();  d != a->sinks().end();  ++d )
00218     if (  (*d)->log( msg )  )
00219       msg.setReactedTo ( true );
00220 
00221   possiblyAbOrEx ( msg.xid().severity.getLevel(),
00222                    a->abortThreshold().getLevel(),
00223                    a->exitThreshold().getLevel()   );   // $$ mf 3/17/04
00224 
00225   // -----  restore, if we poked above:
00226   //
00227   if ( updateProcess    )  msg.setProcess( "" );
00228   if ( updateModule     )  msg.setModule( "" );
00229   if ( updateSubroutine )  msg.setSubroutine( "" );
00230 
00231   return  *this;
00232 
00233 }  // operator()( )
00234 
00235 
00236 void ErrorLog::setModule( const ELstring & modName )  {
00237 
00238   module = modName;
00239 
00240 }  // setModule()
00241 
00242 
00243 void ErrorLog::setPackage( const ELstring & pkgName )  {
00244 
00245   setModule( pkgName );
00246 
00247 }  // setPackage()
00248 
00249 
00250 ErrorLog & ErrorLog::operator() (int nbytes, char * data)  {
00251 
00252   ELrecv ( nbytes, data, module );
00253   return  *this;
00254 
00255 }  // operator() (nbytes, data)
00256 
00257 ErrorLog & ErrorLog::operator<<( void (* f)(ErrorLog &) )  {
00258   #ifdef ErrorLogOUTPUT_TRACE
00259     std::cout << "=:=:=: ErrorLog output trace:  f at " << std::hex << f
00260               << std::endl;
00261   #endif
00262   if (discarding) return *this;
00263   f( *this );
00264   return  *this;
00265 
00266 }  // operator<<()
00267 
00268 
00269 ErrorLog & ErrorLog::emitToken( const ELstring & s )  {
00270 
00271   #ifdef ErrorLogEMIT_TRACE
00272     std::cout << " =:=:=: ErrorLog emit trace:  string is: " << s << "\n";
00273   #endif
00274 
00275   if ( ! a->msgIsActive )
00276     (*this) ( ELunspecified, "..." );
00277 
00278   a->msg.emitToken( s );
00279 
00280   #ifdef ErrorLogEMIT_TRACE
00281     std::cout << " =:=:=: ErrorLog emit trace:  return from a->msg.emitToken()\n";
00282   #endif
00283 
00284   return  *this;
00285 
00286 }  // emitToken()
00287 
00288 
00289 ErrorLog & ErrorLog::endmsg()  {
00290 
00291   #ifdef ErrorLogENDMSG_TRACE
00292     std::cout << "=:=:=: endmsg () -- msgIsActive = " << a->msgIsActive
00293               << std::endl;
00294   #endif
00295 
00296   if ( a->msgIsActive )  {
00297     #ifdef ErrorLogENDMSG_TRACE
00298       std::cout << "=:=:=: endmsg () -- finishMsg started\n";
00299     #endif
00300     a->finishMsg();
00301     #ifdef ErrorLogENDMSG_TRACE
00302       std::cout << "=:=:=: endmsg () -- finishMsg completed\n";
00303     #endif
00304       a->clearMsg();
00305     }
00306     return  *this;
00307 
00308 }  // endmsg()
00309 
00310 // ----------------------------------------------------------------------
00311 // Advanced Control Options:
00312 // ----------------------------------------------------------------------
00313 
00314 bool ErrorLog::setSpaceAfterInt(bool space) {
00315   bool temp = spaceAfterInt;
00316   spaceAfterInt = space;
00317   return temp;
00318 }
00319 
00320 int ErrorLog::setHexTrigger (int trigger) {
00321   int oldTrigger = hexTrigger;
00322   hexTrigger = trigger;
00323   return oldTrigger;
00324 }
00325 
00326 ELseverityLevel ErrorLog::setDiscardThreshold (ELseverityLevel sev) {
00327   ELseverityLevel oldSev = discardThreshold;
00328   discardThreshold = sev;
00329   return oldSev;
00330 }
00331 
00332 void ErrorLog::setDebugVerbosity (int debugVerbosity) {
00333   debugVerbosityLevel = debugVerbosity;
00334 }
00335 
00336 void ErrorLog::setDebugMessages (ELseverityLevel sev, ELstring id) {
00337   debugSeverityLevel = sev;
00338   debugMessageId = id;
00339 }
00340 
00341 bool ErrorLog::getELdestControl (const ELstring & name,
00342                                        ELdestControl & theDestControl) const {
00343   return a->getELdestControl(name, theDestControl);
00344 }
00345 
00346 // ----------------------------------------------------------------------
00347 // Obtaining Information:
00348 // ----------------------------------------------------------------------
00349 
00350 ELstring ErrorLog::moduleName() const { return module; }
00351 ELstring ErrorLog::subroutineName() const { return subroutine; }
00352 
00353 // ----------------------------------------------------------------------
00354 // Global endmsg:
00355 // ----------------------------------------------------------------------
00356 
00357 void endmsg( ErrorLog & log )  { log.endmsg(); }
00358 
00359 // ----------------------------------------------------------------------
00360 // operator<< for integer types
00361 // ----------------------------------------------------------------------
00362 
00363 ErrorLog & operator<<( ErrorLog & e, int n)  {
00364   if (e.discarding) return e;
00365   std::ostringstream  ost;
00366   ost << n;
00367   int m = (n<0) ? -n : n;
00368   if ( (e.hexTrigger >= 0) && (m >= e.hexTrigger) ) {
00369     ost << " [0x"
00370         << std::hex << std::setw(8) << std::setfill('0')
00371         << n << "] ";
00372   } else {
00373     if (e.spaceAfterInt) ost << " ";                    // $$mf 3/17/04
00374   }
00375   return e.emitToken( ost.str() );
00376 }
00377 
00378 ErrorLog & operator<<( ErrorLog & e, unsigned int n)  {
00379   if (e.discarding) return e;
00380   std::ostringstream  ost;
00381   ost << n;
00382   if ( (e.hexTrigger >= 0) &&
00383        (n >= static_cast<unsigned int>(e.hexTrigger)) ) {
00384     ost << "[0x"
00385         << std::hex << std::setw(8) << std::setfill('0')
00386         << n << "] ";
00387   } else {
00388     if (e.spaceAfterInt) ost << " ";                    // $$mf 3/17/04
00389   }
00390   return e.emitToken( ost.str() );
00391 }
00392 
00393 ErrorLog & operator<<( ErrorLog & e, long n)  {
00394   if (e.discarding) return e;
00395   std::ostringstream  ost;
00396   ost << n;
00397   long m = (n<0) ? -n : n;
00398   if ( (e.hexTrigger >= 0) && (m >= e.hexTrigger) ) {
00399     int width = 8;
00400     if ( static_cast<unsigned long>(n) > 0xFFFFFFFFL ) width = 16;
00401     ost << "[0x"
00402         << std::hex << std::setw(width) << std::setfill('0')
00403         << n << "] ";
00404   } else {
00405     if (e.spaceAfterInt) ost << " ";                    // $$mf 3/17/04
00406   }
00407   return  e.emitToken( ost.str() );
00408 }
00409 
00410 ErrorLog & operator<<( ErrorLog & e, unsigned long n)  {
00411   if (e.discarding) return e;
00412   std::ostringstream  ost;
00413   ost << n;
00414   if ( (e.hexTrigger >= 0) &&
00415        (n >= static_cast<unsigned long>(e.hexTrigger)) ) {
00416     int width = 8;
00417     if ( n > 0xFFFFFFFFL ) width = 16;
00418     ost << "[0x"
00419         << std::hex << std::setw(width) << std::setfill('0')
00420         << n << "] ";
00421   } else {
00422     if (e.spaceAfterInt) ost << " ";                    // $$mf 3/17/04
00423   }
00424   return  e.emitToken( ost.str() );
00425 }
00426 
00427 ErrorLog & operator<<( ErrorLog & e, short n)  {
00428   if (e.discarding) return e;
00429   std::ostringstream  ost;
00430   ost << n;
00431   short m = (n<0) ? -n : n;
00432   if ( (e.hexTrigger >= 0) && (m >= e.hexTrigger) ) {
00433     ost << "[0x"
00434         << std::hex << std::setw(4) << std::setfill('0')
00435         << n << "] ";
00436   } else {
00437     if (e.spaceAfterInt) ost << " ";                    // $$mf 3/17/04
00438   }
00439   return  e.emitToken( ost.str() );
00440 }
00441 
00442 ErrorLog & operator<<( ErrorLog & e, unsigned short n)  {
00443   if (e.discarding) return e;
00444   std::ostringstream  ost;
00445   ost << n;
00446   if ( (e.hexTrigger >= 0) && (n >= e.hexTrigger) ) {
00447     ost << "[0x"
00448         << std::hex << std::setw(4) << std::setfill('0')
00449         << n << "] ";
00450   } else {
00451     if (e.spaceAfterInt) ost << " ";                    // $$mf 3/17/04
00452   }
00453   return  e.emitToken( ost.str() );
00454 }
00455 
00456 
00457 // ----------------------------------------------------------------------
00458 // operator<< for const char[]
00459 // ----------------------------------------------------------------------
00460 
00461 ErrorLog & operator<<( ErrorLog & e, const char s[] ) {
00462   // Exactly equivalent to the general template.
00463   // If this is not provided explicitly, then the template will
00464   // be instantiated once for each length of string ever used.
00465   if (e.discarding) return e;
00466   std::ostringstream  ost;
00467   ost << s << ' ';
00468   return  e.emitToken( ost.str() );
00469 }
00470 
00471 
00472 // ----------------------------------------------------------------------
00473 
00474 
00475 } // end of namespace service  
00476 } // end of namespace edm