From 774f630e141fe8972d326027fa704caa06dc672b Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 10 Jun 2022 02:15:10 +0700 Subject: [PATCH] Update Log class. --- src/base/io/log/Log.cpp | 286 ++++++++++++++++++++++++---------------- src/base/io/log/Log.h | 37 ++++-- 2 files changed, 202 insertions(+), 121 deletions(-) diff --git a/src/base/io/log/Log.cpp b/src/base/io/log/Log.cpp index c20f85c7..587f3453 100644 --- a/src/base/io/log/Log.cpp +++ b/src/base/io/log/Log.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2019 Spudz76 - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2022 SChernykh + * Copyright (c) 2016-2022 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,9 +15,16 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining + * it with OpenSSL (or a modified version of that library), containing parts + * covered by the terms of OpenSSL License and SSLeay License, the licensors + * of this Program grant you additional permission to convey the resulting work. */ -#ifdef WIN32 +#ifdef XMRIG_OS_WIN # include # include #endif @@ -25,40 +32,149 @@ #include #include +#include #include #include #include -#include -#include #include #include "base/io/log/Log.h" -#include "base/kernel/interfaces/ILogBackend.h" #include "base/tools/Chrono.h" -#include "base/tools/Object.h" + + +#ifdef XMRIG_FEATURE_EVENTS +# include "base/kernel/Events.h" +# include "base/kernel/events/LogEvent.h" +# include "base/kernel/private/LogConfig.h" +# include "base/kernel/Process.h" +#else +# include "base/kernel/interfaces/ILogBackend.h" +#endif namespace xmrig { +bool Log::m_background = false; +bool Log::m_colors = true; +LogPrivate *Log::d = nullptr; +uint32_t Log::m_verbose = 0; + + +static char buf[Log::kMaxBufferSize]{}; +static std::mutex mutex; + + static const char *colors_map[] = { - RED_BOLD_S, // EMERG - RED_BOLD_S, // ALERT - RED_BOLD_S, // CRIT - RED_S, // ERR - YELLOW_S, // WARNING - WHITE_BOLD_S, // NOTICE - nullptr, // INFO -# ifdef WIN32 - BLACK_BOLD_S // DEBUG + RED_BOLD_S "E ", // EMERG + RED_BOLD_S "A ", // ALERT + RED_BOLD_S "C ", // CRIT + RED_S "E ", // ERR + YELLOW_S "W ", // WARNING + WHITE_BOLD_S "N ", // NOTICE + "I ", // INFO + "1 ", // V1 + "2 ", // V2 + "3 ", // V3 + "4 ", // V4 +# ifdef XMRIG_OS_WIN + BLACK_BOLD_S "5 ", // V5 + BLACK_BOLD_S "D " // DEBUG # else - BRIGHT_BLACK_S // DEBUG + BRIGHT_BLACK_S "5 ", // V5 + BRIGHT_BLACK_S "D " // DEBUG # endif }; +static void log_endl(size_t &size) +{ +# ifdef XMRIG_OS_WIN + memcpy(buf + size, CLEAR "\r\n", 7); + size += 6; +# else + memcpy(buf + size, CLEAR "\n", 6); + size += 5; +# endif +} + +static void log_color(Log::Level level, size_t &size) +{ + if (level == Log::NONE) { + return; + } + + const char *color = colors_map[level]; + if (color == nullptr) { + return; + } + + const size_t s = strlen(color); + memcpy(buf + size, color, s); // NOLINT(bugprone-not-null-terminated-result) + + size += s; +} + + +static uint64_t log_timestamp(Log::Level level, size_t &size, size_t &offset) +{ + const uint64_t ms = Chrono::currentMSecsSinceEpoch(); + + if (level == Log::NONE) { + return ms; + } + + time_t now = ms / 1000; + tm stime{}; + +# ifdef XMRIG_OS_WIN + localtime_s(&stime, &now); +# else + localtime_r(&now, &stime); +# endif + + const int rc = snprintf(buf, sizeof(buf) - 1, "[%d-%02d-%02d %02d:%02d:%02d" BLACK_BOLD(".%03d") "] ", + stime.tm_year + 1900, + stime.tm_mon + 1, + stime.tm_mday, + stime.tm_hour, + stime.tm_min, + stime.tm_sec, + static_cast(ms % 1000) + ); + + if (rc > 0) { + size = offset = static_cast(rc); + } + + return ms; +} + + +#ifdef XMRIG_FEATURE_EVENTS +static void log_print(Log::Level level, const char *fmt, va_list args) +{ + size_t size = 0; + size_t offset = 0; + + std::lock_guard lock(mutex); + + const uint64_t ts = log_timestamp(level, size, offset); + log_color(level, size); + + const int rc = vsnprintf(buf + size, sizeof(buf) - offset - 32, fmt, args); + if (rc < 0) { + return; + } + + size += std::min(static_cast(rc), sizeof(buf) - offset - 32); + log_endl(size); + + Process::events().post(ts, level, buf, offset, size); +} +#else class LogPrivate { public: @@ -70,46 +186,43 @@ public: inline ~LogPrivate() { - for (auto backend : m_backends) { + for (auto backend : backends) { delete backend; } } - inline void add(ILogBackend *backend) { m_backends.push_back(backend); } - - void print(Log::Level level, const char *fmt, va_list args) { size_t size = 0; size_t offset = 0; - std::lock_guard lock(m_mutex); + std::lock_guard lock(mutex); - if (Log::isBackground() && m_backends.empty()) { + if (Log::isBackground() && backends.empty()) { return; } - const uint64_t ts = timestamp(level, size, offset); - color(level, size); + const uint64_t ts = log_timestamp(level, size, offset); + log_color(level, size); - const int rc = vsnprintf(m_buf + size, sizeof (m_buf) - offset - 32, fmt, args); + const int rc = vsnprintf(buf + size, sizeof (buf) - offset - 32, fmt, args); if (rc < 0) { return; } - size += std::min(static_cast(rc), sizeof (m_buf) - offset - 32); - endl(size); + size += std::min(static_cast(rc), sizeof (buf) - offset - 32); + log_endl(size); - std::string txt(m_buf); + std::string txt(buf); size_t i = 0; while ((i = txt.find(CSI)) != std::string::npos) { txt.erase(i, txt.find('m', i) - i + 1); } - if (!m_backends.empty()) { - for (auto backend : m_backends) { - backend->print(ts, level, m_buf, offset, size, true); + if (!backends.empty()) { + for (auto backend : backends) { + backend->print(ts, level, buf, offset, size, true); backend->print(ts, level, txt.c_str(), offset ? (offset - 11) : 0, txt.size(), false); } } @@ -120,94 +233,21 @@ public: } -private: - inline uint64_t timestamp(Log::Level level, size_t &size, size_t &offset) - { - const uint64_t ms = Chrono::currentMSecsSinceEpoch(); - - if (level == Log::NONE) { - return ms; - } - - time_t now = ms / 1000; - tm stime{}; - -# ifdef _WIN32 - localtime_s(&stime, &now); -# else - localtime_r(&now, &stime); -# endif - - const int rc = snprintf(m_buf, sizeof(m_buf) - 1, "[%d-%02d-%02d %02d:%02d:%02d" BLACK_BOLD(".%03d") "] ", - stime.tm_year + 1900, - stime.tm_mon + 1, - stime.tm_mday, - stime.tm_hour, - stime.tm_min, - stime.tm_sec, - static_cast(ms % 1000) - ); - - if (rc > 0) { - size = offset = static_cast(rc); - } - - return ms; - } - - - inline void color(Log::Level level, size_t &size) - { - if (level == Log::NONE) { - return; - } - - const char *color = colors_map[level]; - if (color == nullptr) { - return; - } - - const size_t s = strlen(color); - memcpy(m_buf + size, color, s); - - size += s; - } - - - inline void endl(size_t &size) - { -# ifdef _WIN32 - memcpy(m_buf + size, CLEAR "\r\n", 7); - size += 6; -# else - memcpy(m_buf + size, CLEAR "\n", 6); - size += 5; -# endif - } - - - char m_buf[Log::kMaxBufferSize]{}; - std::mutex m_mutex; - std::vector m_backends; + std::vector backends; }; +#endif -bool Log::m_background = false; -bool Log::m_colors = true; -LogPrivate *Log::d = nullptr; -uint32_t Log::m_verbose = 0; - - -} /* namespace xmrig */ - +} // namespace xmrig +#ifndef XMRIG_FEATURE_EVENTS void xmrig::Log::add(ILogBackend *backend) { assert(d != nullptr); if (d) { - d->add(backend); + d->backends.push_back(backend); } } @@ -223,18 +263,25 @@ void xmrig::Log::init() { d = new LogPrivate(); } +#endif void xmrig::Log::print(const char *fmt, ...) { +# ifndef XMRIG_FEATURE_EVENTS if (!d) { return; } +# endif va_list args{}; va_start(args, fmt); +# ifdef XMRIG_FEATURE_EVENTS + log_print(NONE, fmt, args); +# else d->print(NONE, fmt, args); +# endif va_end(args); } @@ -242,14 +289,33 @@ void xmrig::Log::print(const char *fmt, ...) void xmrig::Log::print(Level level, const char *fmt, ...) { +# ifndef XMRIG_FEATURE_EVENTS if (!d) { return; } +# endif va_list args{}; va_start(args, fmt); +# ifdef XMRIG_FEATURE_EVENTS + log_print(level, fmt, args); +# else d->print(level, fmt, args); +# endif va_end(args); } + + +void xmrig::Log::setVerbose(uint32_t verbose) +{ + static constexpr uint32_t kMaxVerbose = +# ifdef XMRIG_FEATURE_EVENTS + LogConfig::kMaxVerbose; +# else + 5U; +# endif + + m_verbose = std::min(verbose, kMaxVerbose); +} diff --git a/src/base/io/log/Log.h b/src/base/io/log/Log.h index d4c0a319..16965749 100644 --- a/src/base/io/log/Log.h +++ b/src/base/io/log/Log.h @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2019 Spudz76 - * Copyright (c) 2018-2021 SChernykh - * Copyright (c) 2016-2021 XMRig , + * Copyright (c) 2018-2022 SChernykh + * Copyright (c) 2016-2022 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +15,13 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining + * it with OpenSSL (or a modified version of that library), containing parts + * covered by the terms of OpenSSL License and SSLeay License, the licensors + * of this Program grant you additional permission to convey the resulting work. */ #ifndef XMRIG_LOG_H @@ -44,16 +51,25 @@ public: WARNING, // warning conditions NOTICE, // normal but significant condition INFO, // informational + V1, // Verbose + V2, // Verbose + V3, // Verbose + V4, // Verbose + V5, // Verbose DEBUG, // debug-level messages }; constexpr static size_t kMaxBufferSize = 16384; +# ifndef XMRIG_FEATURE_EVENTS static void add(ILogBackend *backend); static void destroy(); static void init(); +# endif + static void print(const char *fmt, ...); static void print(Level level, const char *fmt, ...); + static void setVerbose(uint32_t verbose); static inline bool isBackground() { return m_background; } static inline bool isColors() { return m_colors; } @@ -61,7 +77,6 @@ public: static inline uint32_t verbose() { return m_verbose; } static inline void setBackground(bool background) { m_background = background; } static inline void setColors(bool colors) { m_colors = colors; } - static inline void setVerbose(uint32_t verbose) { m_verbose = verbose; } private: static bool m_background; @@ -143,12 +158,12 @@ private: #define LOG_WARN(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__) #define LOG_NOTICE(x, ...) xmrig::Log::print(xmrig::Log::NOTICE, x, ##__VA_ARGS__) #define LOG_INFO(x, ...) xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__) -#define LOG_VERBOSE(x, ...) if (xmrig::Log::verbose() > 0) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); } -#define LOG_V1(x, ...) if (xmrig::Log::verbose() > 0) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); } -#define LOG_V2(x, ...) if (xmrig::Log::verbose() > 1) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); } -#define LOG_V3(x, ...) if (xmrig::Log::verbose() > 2) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); } -#define LOG_V4(x, ...) if (xmrig::Log::verbose() > 3) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); } -#define LOG_V5(x, ...) if (xmrig::Log::verbose() > 4) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); } +#define LOG_VERBOSE(x, ...) if (xmrig::Log::verbose() > 0) { xmrig::Log::print(xmrig::Log::V1, x, ##__VA_ARGS__); } +#define LOG_V1(x, ...) if (xmrig::Log::verbose() > 0) { xmrig::Log::print(xmrig::Log::V1, x, ##__VA_ARGS__); } +#define LOG_V2(x, ...) if (xmrig::Log::verbose() > 1) { xmrig::Log::print(xmrig::Log::V2, x, ##__VA_ARGS__); } +#define LOG_V3(x, ...) if (xmrig::Log::verbose() > 2) { xmrig::Log::print(xmrig::Log::V3, x, ##__VA_ARGS__); } +#define LOG_V4(x, ...) if (xmrig::Log::verbose() > 3) { xmrig::Log::print(xmrig::Log::V4, x, ##__VA_ARGS__); } +#define LOG_V5(x, ...) if (xmrig::Log::verbose() > 4) { xmrig::Log::print(xmrig::Log::V5, x, ##__VA_ARGS__); } #ifdef APP_DEBUG # define LOG_DEBUG(x, ...) xmrig::Log::print(xmrig::Log::DEBUG, x, ##__VA_ARGS__) @@ -165,7 +180,7 @@ private: #endif -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_LOG_H */ +#endif // XMRIG_LOG_H