Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:44

0001 #include "FWCore/MessageLogger/interface/AbstractMLscribe.h"
0002 #include "FWCore/MessageLogger/interface/ErrorObj.h"
0003 #include "FWCore/MessageLogger/interface/MessageLoggerQ.h"
0004 #include "FWCore/Utilities/interface/EDMException.h"
0005 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0006 
0007 #include <cstring>
0008 #include <iostream>
0009 
0010 //////////////////////////////////////////////////////////////////////
0011 //
0012 // DO NOT replace the internal memcpy() calls by assignment or by
0013 // any other form of copying unless you first understand in depth
0014 // all of the alignment issues involved
0015 //
0016 //////////////////////////////////////////////////////////////////////
0017 
0018 // Change Log
0019 //
0020 // 1 - 3/9/07 mf
0021 //  Addition of JOB command, to be used by --jobreport
0022 // 2 - 6/19/07 mf
0023 //  Addition of MOD command, to be used by --mode
0024 // 3 - 7/24/07 mf
0025 //  Addition of SHT command, to be used when no .cfg file was given
0026 // 4 - 7/25/07 mf
0027 //  Change of each mommand function to start with MLq, e.g. MLqLOG
0028 // 5 - 8/7/07 mf
0029 //  Addition of FLS command, to be used by FlushMessageLog
0030 // 6 - 8/16/07 mf
0031 //  Addition of GRP command, to be used by GroupLogStatistics
0032 // 7 - 6/18/08 mf
0033 //  Addition of JRS command, to be used by SummarizeInJobReport
0034 // 8 - 10/24/08 mf
0035 //  Support for singleThread
0036 // 9 - 8/6/09  mf
0037 //      handshaked() method to support cleaner abstraction of scribes
0038 // 10 - 8/7/09  mf, crj
0039 //      major down-functioning:  the actual dealing with buffer of the
0040 //      SingleConsumerQ is moved off into MainThreadMLscribe.
0041 // 11 - 8/10/09 mf, cdj
0042 //      StandAloneScribe - a class that gets installed as the scribe if
0043 //      no presence is created at all.  Enables easy stand-alone use of the
0044 //      logger
0045 // 12 - 8/10/09 mf, cdj
0046 //      Removal of use of singleThread from this class - does not need it any
0047 //  longer
0048 // 13 - 8/10/09 mf
0049 //      Special control of standAlone message logging
0050 // 14 - 8/12/09 mf, cdj
0051 //      Better ownership management of standAlone or other scribe
0052 
0053 using namespace edm;
0054 
0055 // ChangeLog 11
0056 namespace {
0057   class StandAloneScribe : public edm::service::AbstractMLscribe {
0058   public:
0059     StandAloneScribe() {}
0060 
0061     StandAloneScribe(const StandAloneScribe &) = delete;  // stop default
0062 
0063     const StandAloneScribe &operator=(const StandAloneScribe &) = delete;  // stop default
0064 
0065     // ---------- member functions ---------------------------
0066 
0067     void runCommand(edm::MessageLoggerQ::OpCode opcode, void *operand) override;
0068 
0069   private:
0070     // ---------- member data --------------------------------
0071   };
0072 
0073   void StandAloneScribe::runCommand(edm::MessageLoggerQ::OpCode opcode, void *operand) {
0074     //even though we don't print, have to clean up memory
0075     switch (opcode) {
0076       case edm::MessageLoggerQ::LOG_A_MESSAGE: {
0077         edm::ErrorObj *errorobj_p = static_cast<edm::ErrorObj *>(operand);
0078         if (MessageLoggerQ::ignore  // ChangeLog 13
0079             (errorobj_p->xid().severity, errorobj_p->xid().id)) {
0080           delete errorobj_p;
0081           break;
0082         }
0083         if (errorobj_p->is_verbatim()) {
0084           std::cerr << errorobj_p->fullText() << std::endl;
0085         } else {
0086           std::cerr << "%MSG" << errorobj_p->xid().severity.getSymbol() << " " << errorobj_p->xid().id << ": \n"
0087                     << errorobj_p->fullText() << "\n"
0088                     << "%MSG" << std::endl;
0089         }
0090         delete errorobj_p;
0091         break;
0092       }
0093       case edm::MessageLoggerQ::JOBMODE:
0094       case edm::MessageLoggerQ::GROUP_STATS: {
0095         std::string *string_p = static_cast<std::string *>(operand);
0096         delete string_p;
0097         break;
0098       }
0099       default:
0100         break;
0101     }
0102   }
0103 
0104   // Changelog 14
0105   std::shared_ptr<StandAloneScribe> obtainStandAloneScribePtr() {
0106     static auto standAloneScribe_ptr = std::make_shared<StandAloneScribe>();
0107     return standAloneScribe_ptr;
0108   }
0109 
0110 }  // end of anonymous namespace
0111 
0112 std::shared_ptr<edm::service::AbstractMLscribe> MessageLoggerQ::mlscribe_ptr = obtainStandAloneScribePtr();
0113 // changeLog 8, 11, 14
0114 
0115 MessageLoggerQ::MessageLoggerQ() {}
0116 
0117 MessageLoggerQ::~MessageLoggerQ() {}
0118 
0119 MessageLoggerQ *MessageLoggerQ::instance() {
0120   CMS_THREAD_SAFE static MessageLoggerQ queue;
0121   return &queue;
0122 }  // MessageLoggerQ::instance()
0123 
0124 void MessageLoggerQ::setMLscribe_ptr(std::shared_ptr<edm::service::AbstractMLscribe> m)  // changeLog 8, 14
0125 {
0126   if (!m) {
0127     mlscribe_ptr = obtainStandAloneScribePtr();
0128   } else {
0129     mlscribe_ptr = m;
0130   }
0131 }  // MessageLoggerQ::setMLscribe_ptr(m)
0132 
0133 void MessageLoggerQ::simpleCommand(OpCode opcode, void *operand)  // changeLog 8, 10
0134 {
0135   mlscribe_ptr->runCommand(opcode, operand);
0136 }  // simpleCommand
0137 
0138 void MessageLoggerQ::handshakedCommand(OpCode opcode,
0139                                        void *operand,
0140                                        std::string const &commandMnemonic) {  // Change Log 10
0141   try {
0142     mlscribe_ptr->runCommand(opcode, operand);
0143   } catch (edm::Exception &ex) {
0144     ex << "\n The preceding exception was thrown in MessageLoggerScribe\n";
0145     ex << "and forwarded to the main thread from the Messages thread.";
0146     std::cerr << "exception from MessageLoggerQ::" << commandMnemonic << " - exception what() is \n" << ex.what();
0147     // TODO - get the above text into the what itself
0148     throw ex;
0149   }
0150 }  // handshakedCommand
0151 
0152 void MessageLoggerQ::MLqEND() { simpleCommand(END_THREAD, (void *)nullptr); }  // MessageLoggerQ::END()
0153 
0154 void MessageLoggerQ::MLqSHT() { simpleCommand(SHUT_UP, (void *)nullptr); }  // MessageLoggerQ::SHT()
0155 
0156 void MessageLoggerQ::MLqLOG(ErrorObj *p) {
0157   simpleCommand(LOG_A_MESSAGE, static_cast<void *>(p));
0158 }  // MessageLoggerQ::LOG()
0159 
0160 void MessageLoggerQ::MLqCFG(ParameterSet *p) { handshakedCommand(CONFIGURE, p, "CFG"); }  // MessageLoggerQ::CFG()
0161 
0162 void MessageLoggerQ::MLqSUM() { simpleCommand(SUMMARIZE, nullptr); }  // MessageLoggerQ::SUM()
0163 
0164 void MessageLoggerQ::MLqMOD(std::string *jm) {
0165   simpleCommand(JOBMODE, static_cast<void *>(jm));
0166 }  // MessageLoggerQ::MOD()
0167 
0168 void MessageLoggerQ::MLqFLS()  // Change Log 5
0169 {
0170   // The ConfigurationHandshake, developed for synchronous CFG, contains a
0171   // place to convey exception information.  FLS does not need this, nor does
0172   // it need the parameter set, but we are reusing ConfigurationHandshake
0173   // rather than reinventing the mechanism.
0174   handshakedCommand(FLUSH_LOG_Q, nullptr, "FLS");
0175 }  // MessageLoggerQ::FLS()
0176 
0177 void MessageLoggerQ::MLqGRP(std::string *cat_p)  // Change Log 6
0178 {
0179   simpleCommand(GROUP_STATS, static_cast<void *>(cat_p));
0180 }  // MessageLoggerQ::GRP()
0181 
0182 void MessageLoggerQ::MLqJRS(std::map<std::string, double> *sum_p) {
0183   handshakedCommand(FJR_SUMMARY, sum_p, "JRS");
0184 }  // MessageLoggerQ::CFG()
0185 
0186 bool MessageLoggerQ::handshaked(MessageLoggerQ::OpCode const &op)  // changeLog 9
0187 {
0188   return ((op == CONFIGURE) || (op == FLUSH_LOG_Q) || (op == FJR_SUMMARY));
0189 }  // MessageLoggerQ::handshaked(op)
0190 
0191 // change Log 13:
0192 edm::messagelogger::ELseverityLevel MessageLoggerQ::threshold(edm::messagelogger::ELseverityLevel::ELsev_warning);
0193 std::set<std::string> MessageLoggerQ::squelchSet;
0194 void MessageLoggerQ::standAloneThreshold(edm::messagelogger::ELseverityLevel const &severity) { threshold = severity; }
0195 void MessageLoggerQ::squelch(std::string const &category) { squelchSet.insert(category); }
0196 bool MessageLoggerQ::ignore(edm::messagelogger::ELseverityLevel const &severity, std::string const &category) {
0197   if (severity < threshold)
0198     return true;
0199   if (squelchSet.count(category) > 0)
0200     return true;
0201   return false;
0202 }