diff options
author | Yuri Gorshenin <y@maps.me> | 2017-06-06 14:36:33 +0300 |
---|---|---|
committer | Yuri Gorshenin <y@maps.me> | 2017-06-06 16:03:08 +0300 |
commit | 9b98ba29832b37aae8907d5cf92bd41316232146 (patch) | |
tree | 0f41203b23e4e4462a5838386bb076d0ea8df107 /base | |
parent | 3ea5960a80e0a9bf167294a1147505d934616b25 (diff) |
[qt] Implemented log-abort-level flag for Qt Desktop app.
Diffstat (limited to 'base')
-rw-r--r-- | base/logging.cpp | 185 | ||||
-rw-r--r-- | base/logging.hpp | 110 |
2 files changed, 183 insertions, 112 deletions
diff --git a/base/logging.cpp b/base/logging.cpp index 0f1e002a9b..1ceb63e2f7 100644 --- a/base/logging.cpp +++ b/base/logging.cpp @@ -1,5 +1,5 @@ -#include "base/assert.hpp" #include "base/logging.hpp" +#include "base/assert.hpp" #include "base/macros.hpp" #include "base/mutex.hpp" #include "base/thread.hpp" @@ -8,94 +8,139 @@ #include "std/target_os.hpp" //#include "std/windows.hpp" +#include <algorithm> #include <iomanip> #include <iostream> +#include <iterator> #include <mutex> #include <sstream> +#include <vector> namespace my { - class LogHelper - { - int m_threadsCount; - std::map<threads::ThreadID, int> m_threadID; - - int GetThreadID() - { - int & id = m_threadID[threads::GetCurrentThreadID()]; - if (id == 0) - id = ++m_threadsCount; - return id; - } - - my::Timer m_timer; - - char const * m_names[5]; - size_t m_lens[5]; - - public: - LogHelper() : m_threadsCount(0) - { - m_names[0] = "DEBUG"; m_lens[0] = 5; - m_names[1] = "INFO"; m_lens[1] = 4; - m_names[2] = "WARNING"; m_lens[2] = 7; - m_names[3] = "ERROR"; m_lens[3] = 5; - m_names[4] = "CRITICAL"; m_lens[4] = 8; - } - - void WriteProlog(std::ostream & s, LogLevel level) - { - s << "LOG"; - - s << " TID(" << GetThreadID() << ")"; - s << " " << m_names[level]; - - double const sec = m_timer.ElapsedSeconds(); - s << " " << std::setfill(' ') << std::setw(static_cast<int>(16 - m_lens[level])) << sec << " "; - } - }; - - std::mutex g_logMutex; - - void LogMessageDefault(LogLevel level, SrcPoint const & srcPoint, std::string const & msg) - { - std::lock_guard<std::mutex> lock(g_logMutex); +std::string ToString(LogLevel level) +{ + auto const & names = GetLogLevelNames(); + CHECK_LESS(level, names.size(), ()); + return names[level]; +} + +bool FromString(std::string const & s, LogLevel & level) +{ + auto const & names = GetLogLevelNames(); + auto it = std::find(names.begin(), names.end(), s); + if (it == names.end()) + return false; + level = static_cast<LogLevel>(std::distance(names.begin(), it)); + return true; +} + +std::vector<std::string> const & GetLogLevelNames() +{ + static std::vector<std::string> const kNames = { + {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}}; + return kNames; +} - static LogHelper logger; +class LogHelper +{ + int m_threadsCount; + std::map<threads::ThreadID, int> m_threadID; + + int GetThreadID() + { + int & id = m_threadID[threads::GetCurrentThreadID()]; + if (id == 0) + id = ++m_threadsCount; + return id; + } - std::ostringstream out; - logger.WriteProlog(out, level); + my::Timer m_timer; - out << DebugPrint(srcPoint) << msg << std::endl; - std::cerr << out.str(); + char const * m_names[5]; + size_t m_lens[5]; - CHECK_LESS(level, g_LogAbortLevel, ("Abort. Log level is too serious", level)); +public: + LogHelper() : m_threadsCount(0) + { + m_names[0] = "DEBUG"; + m_lens[0] = 5; + m_names[1] = "INFO"; + m_lens[1] = 4; + m_names[2] = "WARNING"; + m_lens[2] = 7; + m_names[3] = "ERROR"; + m_lens[3] = 5; + m_names[4] = "CRITICAL"; + m_lens[4] = 8; } - void LogMessageTests(LogLevel level, SrcPoint const &, std::string const & msg) + void WriteProlog(std::ostream & s, LogLevel level) { - std::lock_guard<std::mutex> lock(g_logMutex); + s << "LOG"; - std::ostringstream out; - out << msg << std::endl; - std::cerr << out.str(); + s << " TID(" << GetThreadID() << ")"; + s << " " << m_names[level]; - CHECK_LESS(level, g_LogAbortLevel, ("Abort. Log level is too serious", level)); + double const sec = m_timer.ElapsedSeconds(); + s << " " << std::setfill(' ') << std::setw(static_cast<int>(16 - m_lens[level])) << sec << " "; } +}; - LogMessageFn LogMessage = &LogMessageDefault; +std::mutex g_logMutex; - LogMessageFn SetLogMessageFn(LogMessageFn fn) - { - std::swap(LogMessage, fn); - return fn; - } +void LogMessageDefault(LogLevel level, SrcPoint const & srcPoint, std::string const & msg) +{ + std::lock_guard<std::mutex> lock(g_logMutex); -#ifdef DEBUG - TLogLevel g_LogLevel = {LDEBUG}; - TLogLevel g_LogAbortLevel = {LERROR}; + static LogHelper logger; + + std::ostringstream out; + logger.WriteProlog(out, level); + + out << DebugPrint(srcPoint) << msg << std::endl; + std::cerr << out.str(); + + CHECK_LESS(level, g_LogAbortLevel, ("Abort. Log level is too serious", level)); +} + +void LogMessageTests(LogLevel level, SrcPoint const &, std::string const & msg) +{ + std::lock_guard<std::mutex> lock(g_logMutex); + + std::ostringstream out; + out << msg << std::endl; + std::cerr << out.str(); + + CHECK_LESS(level, g_LogAbortLevel, ("Abort. Log level is too serious", level)); +} + +LogMessageFn LogMessage = &LogMessageDefault; + +LogMessageFn SetLogMessageFn(LogMessageFn fn) +{ + std::swap(LogMessage, fn); + return fn; +} + +LogLevel GetDefaultLogLevel() +{ +#if defined(DEBUG) + return LDEBUG; #else - TLogLevel g_LogLevel = {LINFO}; - TLogLevel g_LogAbortLevel = {LCRITICAL}; -#endif + return LINFO; +#endif // defined(DEBUG) } + +LogLevel GetDefaultLogAbortLevel() +{ +#if defined(DEBUG) + return LERROR; +#else + return LCRITICAL; +#endif // defined(DEBUG) +} + +TLogLevel g_LogLevel = {GetDefaultLogLevel()}; +TLogLevel g_LogAbortLevel = {GetDefaultLogAbortLevel()}; +} // namespace my diff --git a/base/logging.hpp b/base/logging.hpp index 678a1b1685..fc9fd1d9f0 100644 --- a/base/logging.hpp +++ b/base/logging.hpp @@ -5,54 +5,62 @@ #include "base/src_point.hpp" #include <atomic> +#include <string> namespace my { - enum LogLevel - { - LDEBUG, - LINFO, - LWARNING, - LERROR, - LCRITICAL - }; +enum LogLevel +{ + LDEBUG, + LINFO, + LWARNING, + LERROR, + LCRITICAL +}; - using TLogLevel = std::atomic<LogLevel>; - typedef void (*LogMessageFn)(LogLevel level, SrcPoint const &, std::string const &); +std::string ToString(LogLevel level); +bool FromString(std::string const & s, LogLevel & level); +std::vector<std::string> const & GetLogLevelNames(); - extern LogMessageFn LogMessage; - extern TLogLevel g_LogLevel; - extern TLogLevel g_LogAbortLevel; +using TLogLevel = std::atomic<LogLevel>; +typedef void (*LogMessageFn)(LogLevel level, SrcPoint const &, std::string const &); - /// @return Pointer to previous message function. - LogMessageFn SetLogMessageFn(LogMessageFn fn); +LogLevel GetDefaultLogLevel(); +LogLevel GetDefaultLogAbortLevel(); - void LogMessageDefault(LogLevel level, SrcPoint const & srcPoint, std::string const & msg); - void LogMessageTests(LogLevel level, SrcPoint const & srcPoint, std::string const & msg); +extern LogMessageFn LogMessage; +extern TLogLevel g_LogLevel; +extern TLogLevel g_LogAbortLevel; - /// Scope Guard to temporarily suppress specific log level, for example, in unit tests: - /// ... - /// { - /// LogLevelSuppressor onlyLERRORAndLCriticalLogsAreEnabled; - /// TEST(SomeFunctionWhichHasDebugOrInfoOrWarningLogs(), ()); - /// } - struct ScopedLogLevelChanger - { - LogLevel m_old = g_LogLevel; - ScopedLogLevelChanger(LogLevel temporaryLogLevel = LERROR) { g_LogLevel = temporaryLogLevel; } - ~ScopedLogLevelChanger() { g_LogLevel = m_old; } - }; +/// @return Pointer to previous message function. +LogMessageFn SetLogMessageFn(LogMessageFn fn); + +void LogMessageDefault(LogLevel level, SrcPoint const & srcPoint, std::string const & msg); +void LogMessageTests(LogLevel level, SrcPoint const & srcPoint, std::string const & msg); - struct ScopedLogAbortLevelChanger +/// Scope Guard to temporarily suppress specific log level, for example, in unit tests: +/// ... +/// { +/// LogLevelSuppressor onlyLERRORAndLCriticalLogsAreEnabled; +/// TEST(SomeFunctionWhichHasDebugOrInfoOrWarningLogs(), ()); +/// } +struct ScopedLogLevelChanger +{ + LogLevel m_old = g_LogLevel; + ScopedLogLevelChanger(LogLevel temporaryLogLevel = LERROR) { g_LogLevel = temporaryLogLevel; } + ~ScopedLogLevelChanger() { g_LogLevel = m_old; } +}; + +struct ScopedLogAbortLevelChanger +{ + LogLevel m_old = g_LogAbortLevel; + ScopedLogAbortLevelChanger(LogLevel temporaryLogAbortLevel = LCRITICAL) { - LogLevel m_old = g_LogAbortLevel; - ScopedLogAbortLevelChanger(LogLevel temporaryLogAbortLevel = LCRITICAL) - { - g_LogAbortLevel = temporaryLogAbortLevel; - } - ~ScopedLogAbortLevelChanger() { g_LogAbortLevel = m_old; } - }; -} + g_LogAbortLevel = temporaryLogAbortLevel; + } + ~ScopedLogAbortLevelChanger() { g_LogAbortLevel = m_old; } +}; +} // namespace my using ::my::LDEBUG; using ::my::LINFO; @@ -62,9 +70,27 @@ using ::my::LCRITICAL; // Logging macro. // Example usage: LOG(LINFO, (Calc(), m_Var, "Some string constant")); -#define LOG(level, msg) do { if ((level) < ::my::g_LogLevel) {} \ - else { ::my::LogMessage(level, SRC(), ::my::impl::Message msg);} } while (false) +#define LOG(level, msg) \ + do \ + { \ + if ((level) < ::my::g_LogLevel) \ + { \ + } \ + else \ + { \ + ::my::LogMessage(level, SRC(), ::my::impl::Message msg); \ + } \ + } while (false) // Logging macro with short info (without entry point) -#define LOG_SHORT(level, msg) do { if ((level) < ::my::g_LogLevel) {} \ - else { ::my::LogMessage(level, my::SrcPoint(), ::my::impl::Message msg);} } while (false) +#define LOG_SHORT(level, msg) \ + do \ + { \ + if ((level) < ::my::g_LogLevel) \ + { \ + } \ + else \ + { \ + ::my::LogMessage(level, my::SrcPoint(), ::my::impl::Message msg); \ + } \ + } while (false) |