Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-03-10 03:25:24

0001 #ifndef MessageLogger_MessageLogger_h
0002 #define MessageLogger_MessageLogger_h
0003 
0004 // -*- C++ -*-
0005 //
0006 // Package:     MessageLogger
0007 // Class  :     <none>
0008 // Functions:   LogSystem,   LogError,   LogWarning, LogInfo,     LogDebug
0009 //              LogAbsolute, LogProblem, LogPrint,   LogVerbatim, LogTrace
0010 //               LogImportant
0011 //
0012 
0013 //
0014 // Original Author:  W. Brown and M. Fischler
0015 //         Created:  Fri Nov 11 16:38:19 CST 2005
0016 //     Major Split:  Tue Feb 14 11:00:00 CST 2006
0017 //           See MessageService/interface/MessageLogger.h
0018 //
0019 // =================================================
0020 
0021 // system include files
0022 
0023 #include <memory>
0024 #include <string>
0025 
0026 // user include files
0027 
0028 // forward declarations
0029 
0030 #include "FWCore/MessageLogger/interface/MessageSender.h"
0031 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0032 #include "FWCore/Utilities/interface/EDMException.h"
0033 
0034 namespace edm {
0035 
0036   namespace level {
0037     struct System {
0038       static constexpr const messagelogger::ELseverityLevel level = messagelogger::ELsevere;
0039       constexpr static bool suppress() noexcept { return false; }
0040     };
0041     struct Error {
0042       static constexpr const messagelogger::ELseverityLevel level = messagelogger::ELerror;
0043       static bool suppress() noexcept { return !MessageDrop::instance()->errorEnabled; }
0044     };
0045     struct Warning {
0046       static constexpr const messagelogger::ELseverityLevel level = messagelogger::ELwarning;
0047       static bool suppress() noexcept {
0048         return (MessageDrop::warningAlwaysSuppressed || !MessageDrop::instance()->warningEnabled);
0049       }
0050     };
0051     struct FwkInfo {
0052       static constexpr const messagelogger::ELseverityLevel level = messagelogger::ELfwkInfo;
0053       static bool suppress() noexcept {
0054         return (MessageDrop::fwkInfoAlwaysSuppressed || !MessageDrop::instance()->fwkInfoEnabled);
0055       }
0056     };
0057     struct Info {
0058       static constexpr const messagelogger::ELseverityLevel level = messagelogger::ELinfo;
0059       static bool suppress() noexcept {
0060         return (MessageDrop::infoAlwaysSuppressed || !MessageDrop::instance()->infoEnabled);
0061       }
0062     };
0063     struct Debug {
0064       static constexpr const messagelogger::ELseverityLevel level = messagelogger::ELdebug;
0065       constexpr static bool suppress() noexcept { return false; }
0066     };
0067   }  // namespace level
0068 
0069   template <typename LVL, bool VERBATIM>
0070   class Log {
0071   public:
0072     using ThisLog = Log<LVL, VERBATIM>;
0073     explicit Log(std::string_view id) : ap(LVL::level, id, VERBATIM, LVL::suppress()) {}
0074     Log(ThisLog&&) = default;
0075     Log(ThisLog const&) = delete;
0076     Log& operator=(ThisLog const&) = delete;
0077     Log& operator=(ThisLog&&) = default;
0078     ~Log() = default;
0079 
0080     template <class T>
0081     ThisLog& operator<<(T const& t) {
0082       if (ap.valid())
0083         ap << t;
0084       return *this;
0085     }
0086     ThisLog& operator<<(std::ostream& (*f)(std::ostream&)) {
0087       if (ap.valid())
0088         ap << f;
0089       return *this;
0090     }
0091     ThisLog& operator<<(std::ios_base& (*f)(std::ios_base&)) {
0092       if (ap.valid())
0093         ap << f;
0094       return *this;
0095     }
0096 
0097     template <typename... Args>
0098     ThisLog& format(std::string_view fmt, Args const&... args) {
0099       if (ap.valid())
0100         ap.format(fmt, args...);
0101       return *this;
0102     }
0103 
0104     template <typename F>
0105     ThisLog& log(F&& iF) {
0106       if (ap.valid()) {
0107         iF(ap);
0108       }
0109       return *this;
0110     }
0111 
0112   protected:
0113     Log() = default;
0114     //Want standard copy ctr to be deleted to make compiler errors
0115     // clearer. This does the same thing but with different signature
0116     //Needed for LogDebug and LogTrace macros
0117     Log(std::nullptr_t, ThisLog const& iOther) : ap(iOther.ap) {}
0118 
0119   private:
0120     MessageSender ap;
0121   };
0122   using LogWarning = Log<level::Warning, false>;
0123   using LogError = Log<level::Error, false>;
0124   using LogSystem = Log<level::System, false>;
0125   using LogInfo = Log<level::Info, false>;
0126   using LogFwkInfo = Log<level::FwkInfo, false>;
0127 
0128   using LogVerbatim = Log<level::Info, true>;
0129   using LogFwkVerbatim = Log<level::FwkInfo, true>;
0130   using LogPrint = Log<level::Warning, true>;
0131   using LogProblem = Log<level::Error, true>;
0132   // less judgemental verbatim version of LogError
0133   using LogImportant = Log<level::Error, true>;
0134   using LogAbsolute = Log<level::System, true>;
0135 
0136   void LogStatistics();
0137 
0138   class LogDebug_ : public Log<level::Debug, false> {
0139   public:
0140     LogDebug_() = default;
0141     explicit LogDebug_(std::string_view id, std::string_view file, int line);
0142     //Needed for the LogDebug macro
0143     LogDebug_(Log<level::Debug, false> const& iOther) : Log<level::Debug, false>(nullptr, iOther) {}
0144     LogDebug_(LogDebug_ const&) = delete;
0145     LogDebug_(LogDebug_&&) = default;
0146     LogDebug_& operator=(LogDebug_ const&) = delete;
0147     LogDebug_& operator=(LogDebug_&&) = default;
0148 
0149   private:
0150     std::string_view stripLeadingDirectoryTree(std::string_view file) const;
0151   };  // LogDebug_
0152 
0153   class LogTrace_ : public Log<level::Debug, true> {
0154   public:
0155     LogTrace_() = default;
0156     explicit LogTrace_(std::string_view id) : Log<level::Debug, true>(id) {}
0157     //Needed for the LogTrace macro
0158     LogTrace_(Log<level::Debug, true> const& iOther) : Log<level::Debug, true>(nullptr, iOther) {}
0159     LogTrace_(LogTrace_ const&) = delete;
0160     LogTrace_(LogTrace_&&) = default;
0161     LogTrace_& operator=(LogTrace_ const&) = delete;
0162     LogTrace_& operator=(LogTrace_&&) = default;
0163   };
0164 
0165   namespace impl {
0166     //Needed for LogDebug and LogTrace macros in order to get the
0167     // type on both sides of the ?: to be the same
0168     struct LogDebugAdapter {
0169       //Need an operator with lower precendence than operator<<
0170       LogDebug_ operator|(Log<level::Debug, false>& iOther) { return LogDebug_(iOther); }
0171       LogTrace_ operator|(Log<level::Debug, true>& iOther) { return LogTrace_(iOther); }
0172       LogDebug_ operator|(Log<level::Debug, false>&& iOther) { return LogDebug_(iOther); }
0173       LogTrace_ operator|(Log<level::Debug, true>&& iOther) { return LogTrace_(iOther); }
0174     };
0175   }  // namespace impl
0176 
0177   namespace edmmltest {
0178     struct WarningThatSuppressesLikeLogInfo {
0179       static constexpr const messagelogger::ELseverityLevel level = messagelogger::ELwarning;
0180       static bool suppress() noexcept {
0181         return (MessageDrop::infoAlwaysSuppressed || !MessageDrop::instance()->warningEnabled);
0182       }
0183     };
0184 
0185     using LogWarningThatSuppressesLikeLogInfo = Log<WarningThatSuppressesLikeLogInfo, false>;
0186   }  // end namespace edmmltest
0187 
0188   class Suppress_LogDebug_ {
0189     // With any decent optimization, use of Suppress_LogDebug_ (...)
0190     // including streaming of items to it via operator<<
0191     // will produce absolutely no executable code.
0192   public:
0193     template <class T>
0194     Suppress_LogDebug_& operator<<(T const&) {
0195       return *this;
0196     }
0197     Suppress_LogDebug_& operator<<(std::ostream& (*)(std::ostream&)) { return *this; }
0198     Suppress_LogDebug_& operator<<(std::ios_base& (*)(std::ios_base&)) { return *this; }
0199 
0200     template <typename... Args>
0201     Suppress_LogDebug_& format(std::string_view fmt, Args const&... args) {
0202       return *this;
0203     }
0204 
0205     template <typename F>
0206     Suppress_LogDebug_& log(F&& iF) {
0207       return *this;
0208     }
0209   };  // Suppress_LogDebug_
0210 
0211   bool isDebugEnabled();
0212   bool isInfoEnabled();
0213   bool isFwkInfoEnabled();
0214   bool isWarningEnabled();
0215   void HaltMessageLogging();
0216   void FlushMessageLog();
0217   void clearMessageLog();
0218   void GroupLogStatistics(std::string_view category);
0219   bool isMessageProcessingSetUp();
0220 
0221   // The following two methods have no effect except in stand-alone apps
0222   // that do not create a MessageServicePresence:
0223   void setStandAloneMessageThreshold(edm::messagelogger::ELseverityLevel const& severity);
0224   void squelchStandAloneMessageCategory(std::string const& category);
0225 
0226 }  // namespace edm
0227 
0228 // The preprocessor symbol controlling suppression of LogDebug is EDM_ML_DEBUG.  Thus by default LogDebug is
0229 // If LogDebug is suppressed, all code past the LogDebug(...) is squelched.
0230 // See doc/suppression.txt.
0231 
0232 #ifndef EDM_ML_DEBUG
0233 #define LogDebug(id) true ? edm::Suppress_LogDebug_() : edm::Suppress_LogDebug_()
0234 #define LogTrace(id) true ? edm::Suppress_LogDebug_() : edm::Suppress_LogDebug_()
0235 #else
0236 #define LogDebug(id)                                                                       \
0237   (edm::MessageDrop::debugAlwaysSuppressed || !edm::MessageDrop::instance()->debugEnabled) \
0238       ? edm::LogDebug_()                                                                   \
0239       : edm::impl::LogDebugAdapter() | edm::LogDebug_(id, __FILE__, __LINE__)
0240 #define LogTrace(id)                                                                       \
0241   (edm::MessageDrop::debugAlwaysSuppressed || !edm::MessageDrop::instance()->debugEnabled) \
0242       ? edm::LogTrace_()                                                                   \
0243       : edm::impl::LogDebugAdapter() | edm::LogTrace_(id)
0244 #endif
0245 
0246 // These macros reduce the need to pollute the code with #ifdefs. The
0247 // idea is that the condition is checked only if debugging is enabled.
0248 // That way the condition expression may use variables that are
0249 // declared only if EDM_ML_DEBUG is enabled. If it is disabled, rely
0250 // on the fact that LogDebug/LogTrace should compile to no-op.
0251 #ifdef EDM_ML_DEBUG
0252 #define IfLogDebug(cond, cat) \
0253   if (cond)                   \
0254   LogDebug(cat)
0255 #define IfLogTrace(cond, cat) \
0256   if (cond)                   \
0257   LogTrace(cat)
0258 #else
0259 #define IfLogDebug(cond, cat) LogDebug(cat)
0260 #define IfLogTrace(cond, cat) LogTrace(cat)
0261 #endif
0262 
0263 #endif  // MessageLogger_MessageLogger_h