From e7fabbd47093e05344b9a977ba7641280a64ef32 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 25 Mar 2017 19:27:30 +0000 Subject: [PATCH] easylogging++: add categories --- external/easylogging++/easylogging++.cc | 103 +++++++++++++++++++++++- external/easylogging++/easylogging++.h | 19 +++++ 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/external/easylogging++/easylogging++.cc b/external/easylogging++/easylogging++.cc index cf6958a31..07648dd13 100644 --- a/external/easylogging++/easylogging++.cc +++ b/external/easylogging++/easylogging++.cc @@ -84,6 +84,26 @@ Level LevelHelper::convertFromString(const char* levelStr) { return Level::Unknown; } +Level LevelHelper::convertFromStringPrefix(const char* levelStr) { + if ((strncmp(levelStr, "GLOBAL", 6) == 0) || (strncmp(levelStr, "global", 6) == 0)) + return Level::Global; + if ((strncmp(levelStr, "DEBUG", 5) == 0) || (strncmp(levelStr, "debug", 5) == 0)) + return Level::Debug; + if ((strncmp(levelStr, "INFO", 4) == 0) || (strncmp(levelStr, "info", 4) == 0)) + return Level::Info; + if ((strncmp(levelStr, "WARNING", 7) == 0) || (strncmp(levelStr, "warning", 7) == 0)) + return Level::Warning; + if ((strncmp(levelStr, "ERROR", 5) == 0) || (strncmp(levelStr, "error", 5) == 0)) + return Level::Error; + if ((strncmp(levelStr, "FATAL", 5) == 0) || (strncmp(levelStr, "fatal", 5) == 0)) + return Level::Fatal; + if ((strncmp(levelStr, "VERBOSE", 7) == 0) || (strncmp(levelStr, "verbose", 7) == 0)) + return Level::Verbose; + if ((strncmp(levelStr, "TRACE", 5) == 0) || (strncmp(levelStr, "trace", 5) == 0)) + return Level::Trace; + return Level::Unknown; +} + void LevelHelper::forEachLevel(base::type::EnumType* startIndex, const std::function& fn) { base::type::EnumType lIndexMax = LevelHelper::kMaxValid; do { @@ -1928,6 +1948,79 @@ void VRegistry::setModules(const char* modules) { } } +void VRegistry::setCategories(const char* categories, bool clear) { + base::threading::ScopedLock scopedLock(lock()); + auto insert = [&](std::stringstream& ss, Level level) { + m_categories.push_back(std::make_pair(ss.str(), level)); + }; + + if (clear) + m_categories.clear(); + if (!categories) + return; + + bool isCat = true; + bool isLevel = false; + std::stringstream ss; + Level level = Level::Unknown; + for (; *categories; ++categories) { + switch (*categories) { + case ':': + isLevel = true; + isCat = false; + break; + case ',': + isLevel = false; + isCat = true; + if (!ss.str().empty() && level != Level::Unknown) { + insert(ss, level); + ss.str(std::string("")); + level = Level::Unknown; + } + break; + default: + if (isCat) { + ss << *categories; + } else if (isLevel) { + level = LevelHelper::convertFromStringPrefix(categories); + if (level != Level::Unknown) + categories += strlen(LevelHelper::convertToString(level)) - 1; + } + break; + } + } + if (!ss.str().empty() && level != Level::Unknown) { + insert(ss, level); + } +} + +// Log levels are sorted in a weird way... +static int priority(Level level) { + if (level == Level::Fatal) return 0; + if (level == Level::Error) return 1; + if (level == Level::Warning) return 2; + if (level == Level::Info) return 3; + if (level == Level::Debug) return 4; + if (level == Level::Verbose) return 5; + if (level == Level::Trace) return 6; + return 7; +} + +bool VRegistry::allowed(Level level, const char* category) { + base::threading::ScopedLock scopedLock(lock()); + if (m_categories.empty() || category == nullptr) { + return false; + } else { + std::deque>::const_reverse_iterator it = m_categories.rbegin(); + for (; it != m_categories.rend(); ++it) { + if (base::utils::Str::wildCardMatch(category, it->first.c_str())) { + return priority(level) <= priority(it->second); + } + } + return false; + } +} + bool VRegistry::allowed(base::type::VerboseLevel vlevel, const char* file) { base::threading::ScopedLock scopedLock(lock()); if (m_modules.empty() || file == nullptr) { @@ -2445,7 +2538,7 @@ void Writer::initializeLogger(const std::string& loggerId, bool lookup, bool nee } if (ELPP->hasFlag(LoggingFlag::HierarchicalLogging)) { m_proceed = m_level == Level::Verbose ? m_logger->enabled(m_level) : - LevelHelper::castToInt(m_level) >= LevelHelper::castToInt(ELPP->m_loggingLevel); + ELPP->vRegistry()->allowed(m_level, loggerId.c_str()); } else { m_proceed = m_logger->enabled(m_level); } @@ -2966,6 +3059,14 @@ void Loggers::clearVModules(void) { ELPP->vRegistry()->clearModules(); } +void Loggers::setCategories(const char* categories, bool clear) { + ELPP->vRegistry()->setCategories(categories, clear); +} + +void Loggers::clearCategories(void) { + ELPP->vRegistry()->clearCategories(); +} + // VersionInfo const std::string VersionInfo::version(void) { diff --git a/external/easylogging++/easylogging++.h b/external/easylogging++/easylogging++.h index 8f8a71733..98dcb0b5c 100644 --- a/external/easylogging++/easylogging++.h +++ b/external/easylogging++/easylogging++.h @@ -365,6 +365,7 @@ ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStre #include #include #include +#include #include #include #include @@ -581,6 +582,10 @@ class LevelHelper : base::StaticClass { /// @brief Converts level to associated const char* /// @return Upper case string based level. static const char* convertToString(Level level); + /// @brief Converts from prefix of levelStr to Level + /// @param levelStr Upper case string based level. + /// Lower case is also valid but providing upper case is recommended. + static Level convertFromStringPrefix(const char* levelStr); /// @brief Converts from levelStr to Level /// @param levelStr Upper case string based level. /// Lower case is also valid but providing upper case is recommended. @@ -2454,13 +2459,22 @@ class VRegistry : base::NoCopy, public base::threading::ThreadSafe { return m_level; } + inline void clearCategories(void) { + base::threading::ScopedLock scopedLock(lock()); + m_categories.clear(); + } + inline void clearModules(void) { base::threading::ScopedLock scopedLock(lock()); m_modules.clear(); } + void setCategories(const char* categories, bool clear = true); + void setModules(const char* modules); + bool allowed(Level level, const char* category); + bool allowed(base::type::VerboseLevel vlevel, const char* file); inline const std::map& modules(void) const { @@ -2478,6 +2492,7 @@ class VRegistry : base::NoCopy, public base::threading::ThreadSafe { base::type::VerboseLevel m_level; base::type::EnumType* m_pFlags; std::map m_modules; + std::deque> m_categories; }; } // namespace base class LogMessage { @@ -3897,8 +3912,12 @@ class Loggers : base::StaticClass { static base::type::VerboseLevel verboseLevel(void); /// @brief Sets vmodules as specified (on the fly) static void setVModules(const char* modules); + /// @brief Sets categories as specified (on the fly) + static void setCategories(const char* categories, bool clear = true); /// @brief Clears vmodules static void clearVModules(void); + /// @brief Clears categories + static void clearCategories(void); }; class VersionInfo : base::StaticClass { public: