Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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(fmt::format_string<Args...> format, Args&&... args) {
0099       if (ap.valid())
0100         ap.format(std::move(format), std::forward<Args>(args)...);
0101       return *this;
0102     }
0103 
0104     ThisLog& vformat(std::string_view fmt, fmt::format_args args) {
0105       if (ap.valid())
0106         ap.vformat(fmt, args);
0107       return *this;
0108     }
0109 
0110     template <typename F>
0111     ThisLog& log(F&& iF) {
0112       if (ap.valid()) {
0113         iF(ap);
0114       }
0115       return *this;
0116     }
0117 
0118   protected:
0119     Log() = default;
0120     //Want standard copy ctr to be deleted to make compiler errors
0121     // clearer. This does the same thing but with different signature
0122     //Needed for LogDebug and LogTrace macros
0123     Log(std::nullptr_t, ThisLog const& iOther) : ap(iOther.ap) {}
0124 
0125   private:
0126     MessageSender ap;
0127   };
0128   using LogWarning = Log<level::Warning, false>;
0129   using LogError = Log<level::Error, false>;
0130   using LogSystem = Log<level::System, false>;
0131   using LogInfo = Log<level::Info, false>;
0132   using LogFwkInfo = Log<level::FwkInfo, false>;
0133 
0134   using LogVerbatim = Log<level::Info, true>;
0135   using LogFwkVerbatim = Log<level::FwkInfo, true>;
0136   using LogPrint = Log<level::Warning, true>;
0137   using LogProblem = Log<level::Error, true>;
0138   // less judgemental verbatim version of LogError
0139   using LogImportant = Log<level::Error, true>;
0140   using LogAbsolute = Log<level::System, true>;
0141 
0142   void LogStatistics();
0143 
0144   class LogDebug_ : public Log<level::Debug, false> {
0145   public:
0146     LogDebug_() = default;
0147     explicit LogDebug_(std::string_view id, std::string_view file, int line);
0148     //Needed for the LogDebug macro
0149     LogDebug_(Log<level::Debug, false> const& iOther) : Log<level::Debug, false>(nullptr, iOther) {}
0150     LogDebug_(LogDebug_ const&) = delete;
0151     LogDebug_(LogDebug_&&) = default;
0152     LogDebug_& operator=(LogDebug_ const&) = delete;
0153     LogDebug_& operator=(LogDebug_&&) = default;
0154 
0155   private:
0156     std::string_view stripLeadingDirectoryTree(std::string_view file) const;
0157   };  // LogDebug_
0158 
0159   class LogTrace_ : public Log<level::Debug, true> {
0160   public:
0161     LogTrace_() = default;
0162     explicit LogTrace_(std::string_view id) : Log<level::Debug, true>(id) {}
0163     //Needed for the LogTrace macro
0164     LogTrace_(Log<level::Debug, true> const& iOther) : Log<level::Debug, true>(nullptr, iOther) {}
0165     LogTrace_(LogTrace_ const&) = delete;
0166     LogTrace_(LogTrace_&&) = default;
0167     LogTrace_& operator=(LogTrace_ const&) = delete;
0168     LogTrace_& operator=(LogTrace_&&) = default;
0169   };
0170 
0171   namespace impl {
0172     //Needed for LogDebug and LogTrace macros in order to get the
0173     // type on both sides of the ?: to be the same
0174     struct LogDebugAdapter {
0175       //Need an operator with lower precendence than operator<<
0176       LogDebug_ operator|(Log<level::Debug, false>& iOther) { return LogDebug_(iOther); }
0177       LogTrace_ operator|(Log<level::Debug, true>& iOther) { return LogTrace_(iOther); }
0178       LogDebug_ operator|(Log<level::Debug, false>&& iOther) { return LogDebug_(iOther); }
0179       LogTrace_ operator|(Log<level::Debug, true>&& iOther) { return LogTrace_(iOther); }
0180     };
0181   }  // namespace impl
0182 
0183   namespace edmmltest {
0184     struct WarningThatSuppressesLikeLogInfo {
0185       static constexpr const messagelogger::ELseverityLevel level = messagelogger::ELwarning;
0186       static bool suppress() noexcept {
0187         return (MessageDrop::infoAlwaysSuppressed || !MessageDrop::instance()->warningEnabled);
0188       }
0189     };
0190 
0191     using LogWarningThatSuppressesLikeLogInfo = Log<WarningThatSuppressesLikeLogInfo, false>;
0192   }  // end namespace edmmltest
0193 
0194   class Suppress_LogDebug_ {
0195     // With any decent optimization, use of Suppress_LogDebug_ (...)
0196     // including streaming of items to it via operator<<
0197     // will produce absolutely no executable code.
0198   public:
0199     template <class T>
0200     Suppress_LogDebug_& operator<<(T const&) {
0201       return *this;
0202     }
0203     Suppress_LogDebug_& operator<<(std::ostream& (*)(std::ostream&)) { return *this; }
0204     Suppress_LogDebug_& operator<<(std::ios_base& (*)(std::ios_base&)) { return *this; }
0205 
0206     template <typename... Args>
0207     Suppress_LogDebug_& format(fmt::format_string<Args...> format, Args&&... args) {
0208       return *this;
0209     }
0210 
0211     Suppress_LogDebug_& vformat(std::string_view fmt, fmt::format_args args) { return *this; }
0212 
0213     template <typename F>
0214     Suppress_LogDebug_& log(F&& iF) {
0215       return *this;
0216     }
0217   };  // Suppress_LogDebug_
0218 
0219   bool isDebugEnabled();
0220   bool isInfoEnabled();
0221   bool isFwkInfoEnabled();
0222   bool isWarningEnabled();
0223   void HaltMessageLogging();
0224   void FlushMessageLog();
0225   void clearMessageLog();
0226   void GroupLogStatistics(std::string_view category);
0227   bool isMessageProcessingSetUp();
0228 
0229   // The following two methods have no effect except in stand-alone apps
0230   // that do not create a MessageServicePresence:
0231   void setStandAloneMessageThreshold(edm::messagelogger::ELseverityLevel const& severity);
0232   void squelchStandAloneMessageCategory(std::string const& category);
0233 
0234 }  // namespace edm
0235 
0236 // The preprocessor symbol controlling suppression of LogDebug is EDM_ML_DEBUG.  Thus by default LogDebug is
0237 // If LogDebug is suppressed, all code past the LogDebug(...) is squelched.
0238 // See doc/suppression.txt.
0239 
0240 #ifndef EDM_ML_DEBUG
0241 #define LogDebug(id) true ? edm::Suppress_LogDebug_() : edm::Suppress_LogDebug_()
0242 #define LogTrace(id) true ? edm::Suppress_LogDebug_() : edm::Suppress_LogDebug_()
0243 #else
0244 #define LogDebug(id)                                                                       \
0245   (edm::MessageDrop::debugAlwaysSuppressed || !edm::MessageDrop::instance()->debugEnabled) \
0246       ? edm::LogDebug_()                                                                   \
0247       : edm::impl::LogDebugAdapter() | edm::LogDebug_(id, __FILE__, __LINE__)
0248 #define LogTrace(id)                                                                       \
0249   (edm::MessageDrop::debugAlwaysSuppressed || !edm::MessageDrop::instance()->debugEnabled) \
0250       ? edm::LogTrace_()                                                                   \
0251       : edm::impl::LogDebugAdapter() | edm::LogTrace_(id)
0252 #endif
0253 
0254 // These macros reduce the need to pollute the code with #ifdefs. The
0255 // idea is that the condition is checked only if debugging is enabled.
0256 // That way the condition expression may use variables that are
0257 // declared only if EDM_ML_DEBUG is enabled. If it is disabled, rely
0258 // on the fact that LogDebug/LogTrace should compile to no-op.
0259 #ifdef EDM_ML_DEBUG
0260 #define IfLogDebug(cond, cat) \
0261   if (cond)                   \
0262   LogDebug(cat)
0263 #define IfLogTrace(cond, cat) \
0264   if (cond)                   \
0265   LogTrace(cat)
0266 #else
0267 #define IfLogDebug(cond, cat) LogDebug(cat)
0268 #define IfLogTrace(cond, cat) LogTrace(cat)
0269 #endif
0270 
0271 #endif  // MessageLogger_MessageLogger_h