mirror of
https://github.com/xmrig/xmrig.git
synced 2025-01-03 09:29:46 +00:00
Update Log class.
This commit is contained in:
parent
d6a1c98314
commit
774f630e14
2 changed files with 202 additions and 121 deletions
|
@ -1,7 +1,7 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2022 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2022 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 <winsock2.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
@ -25,40 +32,149 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <uv.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
#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<int>(ms % 1000)
|
||||
);
|
||||
|
||||
if (rc > 0) {
|
||||
size = offset = static_cast<size_t>(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<std::mutex> 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<size_t>(rc), sizeof(buf) - offset - 32);
|
||||
log_endl(size);
|
||||
|
||||
Process::events().post<LogEvent>(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<std::mutex> lock(m_mutex);
|
||||
std::lock_guard<std::mutex> 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<size_t>(rc), sizeof (m_buf) - offset - 32);
|
||||
endl(size);
|
||||
size += std::min(static_cast<size_t>(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<int>(ms % 1000)
|
||||
);
|
||||
|
||||
if (rc > 0) {
|
||||
size = offset = static_cast<size_t>(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<ILogBackend*> m_backends;
|
||||
std::vector<ILogBackend*> 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);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2022 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2022 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
|
|
Loading…
Reference in a new issue