CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/FWCore/MessageLogger/src/MessageLoggerQ.cc

Go to the documentation of this file.
00001 #include "FWCore/MessageLogger/interface/MessageLoggerQ.h"
00002 #include "FWCore/MessageLogger/interface/AbstractMLscribe.h"
00003 #include "FWCore/Utilities/interface/EDMException.h"
00004 #include "FWCore/MessageLogger/interface/ErrorObj.h"
00005 
00006 #include <cstring>
00007 #include <iostream>
00008 
00010 //
00011 // DO NOT replace the internal memcpy() calls by assignment or by
00012 // any other form of copying unless you first understand in depth
00013 // all of the alignment issues involved
00014 //
00016 
00017 // Change Log
00018 // 
00019 // 1 - 3/9/07 mf
00020 //      Addition of JOB command, to be used by --jobreport
00021 // 2 - 6/19/07 mf
00022 //      Addition of MOD command, to be used by --mode
00023 // 3 - 7/24/07 mf
00024 //      Addition of SHT command, to be used when no .cfg file was given
00025 // 4 - 7/25/07 mf
00026 //      Change of each mommand function to start with MLq, e.g. MLqLOG
00027 // 5 - 8/7/07 mf
00028 //      Addition of FLS command, to be used by FlushMessageLog
00029 // 6 - 8/16/07 mf
00030 //      Addition of GRP command, to be used by GroupLogStatistics
00031 // 7 - 6/18/08 mf
00032 //      Addition of JRS command, to be used by SummarizeInJobReport
00033 // 8 - 10/24/08 mf
00034 //      Support for singleThread
00035 // 9 - 8/6/09  mf
00036 //      handshaked() method to support cleaner abstraction of scribes
00037 // 10 - 8/7/09  mf, crj
00038 //      major down-functioning:  the actual dealing with buffer of the 
00039 //      SingleConsumerQ is moved off into MainThreadMLscribe.
00040 // 11 - 8/10/09 mf, cdj
00041 //      StandAloneScribe - a class that gets installed as the scribe if
00042 //      no presence is created at all.  Enables easy stand-alone use of the
00043 //      logger
00044 // 12 - 8/10/09 mf, cdj
00045 //      Removal of use of singleThread from this class - does not need it any
00046 //      longer
00047 // 13 - 8/10/09 mf
00048 //      Special control of standAlone message logging
00049 // 14 - 8/12/09 mf, cdj
00050 //      Better ownership management of standAlone or other scribe
00051 
00052 using namespace edm;
00053 
00054 // ChangeLog 11
00055 namespace {
00056    class StandAloneScribe : public edm::service::AbstractMLscribe {
00057       
00058    public:
00059       StandAloneScribe() {}
00060             
00061       // ---------- member functions ---------------------------
00062       virtual
00063       void  runCommand(edm::MessageLoggerQ::OpCode  opcode, void * operand);
00064       
00065    private:
00066       StandAloneScribe(const StandAloneScribe&); // stop default
00067       
00068       const StandAloneScribe& operator=(const StandAloneScribe&); // stop default
00069       
00070       // ---------- member data --------------------------------
00071       
00072    };      
00073    
00074    void  
00075    StandAloneScribe::runCommand(edm::MessageLoggerQ::OpCode  opcode, void * operand) {
00076       //even though we don't print, have to clean up memory
00077       switch (opcode) {
00078          case edm::MessageLoggerQ::LOG_A_MESSAGE: {
00079             edm::ErrorObj *  errorobj_p = static_cast<edm::ErrorObj *>(operand);
00080             if ( MessageLoggerQ::ignore                         // ChangeLog 13
00081                         (errorobj_p->xid().severity, errorobj_p->xid().id) ) {
00082               delete errorobj_p;
00083               break;
00084             }
00085             if (errorobj_p->is_verbatim()) {
00086               std::cerr<< errorobj_p->fullText() << std::endl;
00087             } else {
00088               std::cerr<< "%MSG" << errorobj_p->xid().severity.getSymbol()
00089                        << " " << errorobj_p->xid().id << ": \n"
00090                        << errorobj_p->fullText() << "\n"
00091                        << "%MSG"
00092                        << std::endl;
00093             }
00094             delete errorobj_p;
00095             break;
00096          }
00097          case edm::MessageLoggerQ::JOBREPORT:
00098          case edm::MessageLoggerQ::JOBMODE:
00099          case edm::MessageLoggerQ::GROUP_STATS:
00100          {
00101             std::string* string_p = static_cast<std::string*> (operand);
00102             delete string_p;
00103             break;
00104          }
00105          default:
00106             break;
00107       }
00108    }   
00109 
00110   // Changelog 14
00111   boost::shared_ptr<StandAloneScribe> obtainStandAloneScribePtr() {   
00112     static boost::shared_ptr<StandAloneScribe> 
00113       standAloneScribe_ptr( new StandAloneScribe );
00114     return standAloneScribe_ptr;
00115   }
00116 
00117 
00118 } // end of anonymous namespace
00119 
00120 boost::shared_ptr<edm::service::AbstractMLscribe>  
00121   MessageLoggerQ::mlscribe_ptr = obtainStandAloneScribePtr();  
00122                                 // changeLog 8, 11, 14
00123 
00124 MessageLoggerQ::MessageLoggerQ()
00125 { }
00126 
00127 
00128 MessageLoggerQ::~MessageLoggerQ()
00129 { }
00130 
00131 
00132 MessageLoggerQ *
00133   MessageLoggerQ::instance()
00134 {
00135   static MessageLoggerQ queue;
00136   return &queue;
00137 }  // MessageLoggerQ::instance()
00138 
00139 void
00140   MessageLoggerQ::setMLscribe_ptr
00141         (boost::shared_ptr<edm::service::AbstractMLscribe> m) // changeLog 8, 14
00142 {
00143   if (!m) { 
00144     mlscribe_ptr = obtainStandAloneScribePtr();
00145   } else {
00146     mlscribe_ptr = m;
00147   }
00148 }  // MessageLoggerQ::setMLscribe_ptr(m)
00149 
00150 void
00151   MessageLoggerQ::simpleCommand(OpCode opcode, void * operand)// changeLog 8, 10
00152 {
00153   mlscribe_ptr->runCommand(opcode, operand);
00154 } // simpleCommand
00155 
00156 void
00157   MessageLoggerQ::handshakedCommand( 
00158         OpCode opcode, 
00159         void * operand,
00160         std::string const & commandMnemonic )
00161 {                                                               // Change Log 10
00162   try {
00163     mlscribe_ptr->runCommand(opcode, operand);
00164   }
00165   catch(edm::Exception& ex)
00166   {
00167     ex << "\n The preceding exception was thrown in MessageLoggerScribe\n";
00168     ex << "and forwarded to the main thread from the Messages thread.";
00169     std::cerr << "exception from MessageLoggerQ::" 
00170               << commandMnemonic << " - exception what() is \n" 
00171               << ex.what();
00172     // TODO - get the above text into the what itself
00173     throw ex;   
00174   }  
00175 }  // handshakedCommand
00176 
00177 void
00178   MessageLoggerQ::MLqEND()
00179 {
00180   simpleCommand (END_THREAD, (void *)0); 
00181 }  // MessageLoggerQ::END()
00182 
00183 void
00184   MessageLoggerQ::MLqSHT()
00185 {
00186   simpleCommand (SHUT_UP, (void *)0); 
00187 }  // MessageLoggerQ::SHT()
00188 
00189 void
00190   MessageLoggerQ::MLqLOG( ErrorObj * p )
00191 {
00192   simpleCommand (LOG_A_MESSAGE, static_cast<void *>(p)); 
00193 }  // MessageLoggerQ::LOG()
00194 
00195 
00196 void
00197   MessageLoggerQ::MLqCFG( ParameterSet * p )
00198 {
00199   handshakedCommand(CONFIGURE, p, "CFG" );
00200 }  // MessageLoggerQ::CFG()
00201 
00202 void
00203 MessageLoggerQ::MLqEXT( service::NamedDestination* p )
00204 {
00205   simpleCommand (EXTERN_DEST, static_cast<void *>(p)); 
00206 }
00207 
00208 void
00209   MessageLoggerQ::MLqSUM( )
00210 {
00211   simpleCommand (SUMMARIZE, 0); 
00212 }  // MessageLoggerQ::SUM()
00213 
00214 void
00215   MessageLoggerQ::MLqJOB( std::string * j )
00216 {
00217   simpleCommand (JOBREPORT, static_cast<void *>(j)); 
00218 }  // MessageLoggerQ::JOB()
00219 
00220 void
00221   MessageLoggerQ::MLqMOD( std::string * jm )
00222 {
00223   simpleCommand (JOBMODE, static_cast<void *>(jm)); 
00224 }  // MessageLoggerQ::MOD()
00225 
00226 
00227 void
00228   MessageLoggerQ::MLqFLS(  )                    // Change Log 5
00229 {
00230   // The ConfigurationHandshake, developed for synchronous CFG, contains a
00231   // place to convey exception information.  FLS does not need this, nor does
00232   // it need the parameter set, but we are reusing ConfigurationHandshake 
00233   // rather than reinventing the mechanism.
00234   handshakedCommand(FLUSH_LOG_Q, 0, "FLS" );
00235 }  // MessageLoggerQ::FLS()
00236 
00237 void
00238   MessageLoggerQ::MLqGRP( std::string * cat_p )         // Change Log 6
00239 {
00240   simpleCommand (GROUP_STATS, static_cast<void *>(cat_p)); 
00241 }  // MessageLoggerQ::GRP()
00242 
00243 void
00244   MessageLoggerQ::MLqJRS( std::map<std::string, double> * sum_p )
00245 {
00246   handshakedCommand(FJR_SUMMARY, sum_p, "JRS" );
00247 }  // MessageLoggerQ::CFG()
00248 
00249 
00250 bool
00251   MessageLoggerQ::handshaked(MessageLoggerQ::OpCode const & op)  // changeLog 9
00252 {
00253    return ( (op == CONFIGURE) || (op == FLUSH_LOG_Q) || (op == FJR_SUMMARY) );
00254 }  // MessageLoggerQ::handshaked(op)
00255 
00256 // change Log 13:
00257 edm::ELseverityLevel MessageLoggerQ::threshold ("WARNING");
00258 std::set<std::string> MessageLoggerQ::squelchSet;
00259 void MessageLoggerQ::standAloneThreshold(std::string const & severity) {
00260   threshold = edm::ELseverityLevel(severity);  
00261 }
00262 void MessageLoggerQ::squelch(std::string const & category) {
00263   squelchSet.insert(category);  
00264 }
00265 bool MessageLoggerQ::ignore ( edm::ELseverityLevel const & severity, 
00266                                std::string const & category ) {
00267   if ( severity < threshold ) return true;
00268   if ( squelchSet.count(category) > 0 ) return true;
00269   return false;
00270 }