aboutsummaryrefslogtreecommitdiff
path: root/external/easylogging++/easylogging++.cc
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2019-06-22 14:42:48 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2019-09-16 16:58:01 +0000
commit32f725d32f8e15f9bd4d0607251ede14c38fd993 (patch)
treef217d7475fabf7353e1738213cf7025bbc22c6c5 /external/easylogging++/easylogging++.cc
parentMerge pull request #5861 (diff)
downloadmonero-32f725d32f8e15f9bd4d0607251ede14c38fd993.tar.xz
Properly format multiline logs
As a side effect, colouring on Windows should now work regardless of version
Diffstat (limited to 'external/easylogging++/easylogging++.cc')
-rw-r--r--external/easylogging++/easylogging++.cc130
1 files changed, 107 insertions, 23 deletions
diff --git a/external/easylogging++/easylogging++.cc b/external/easylogging++/easylogging++.cc
index 2b4c7bbbf..a5a4a64b7 100644
--- a/external/easylogging++/easylogging++.cc
+++ b/external/easylogging++/easylogging++.cc
@@ -18,6 +18,7 @@
#include "easylogging++.h"
#include <unistd.h>
+#include <boost/algorithm/string.hpp>
#if defined(AUTO_INITIALIZE_EASYLOGGINGPP)
INITIALIZE_EASYLOGGINGPP
@@ -133,6 +134,50 @@ static void abort(int status, const std::string& reason) {
#endif // defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG)
}
+static el::Color colorFromLevel(el::Level level)
+{
+ switch (level)
+ {
+ case Level::Error: case Level::Fatal: return el::Color::Red;
+ case Level::Warning: return el::Color::Yellow;
+ case Level::Debug: return el::Color::Green;
+ case Level::Info: return el::Color::Cyan;
+ case Level::Trace: return el::Color::Magenta;
+ default: return el::Color::Default;
+ }
+}
+
+static void setConsoleColor(el::Color color, bool bright)
+{
+#if ELPP_OS_WINDOWS
+ HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
+ switch (color)
+ {
+ case el::Color::Red: SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | (bright ? FOREGROUND_INTENSITY:0)); break;
+ case el::Color::Green: SetConsoleTextAttribute(h_stdout, FOREGROUND_GREEN | (bright ? FOREGROUND_INTENSITY:0)); break;
+ case el::Color::Yellow: SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | (bright ? FOREGROUND_INTENSITY:0)); break;
+ case el::Color::Blue: SetConsoleTextAttribute(h_stdout, FOREGROUND_BLUE | (bright ? FOREGROUND_INTENSITY:0)); break;
+ case el::Color::Magenta: SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_BLUE | (bright ? FOREGROUND_INTENSITY:0)); break;
+ case el::Color::Cyan: SetConsoleTextAttribute(h_stdout, FOREGROUND_GREEN | FOREGROUND_BLUE | (bright ? FOREGROUND_INTENSITY:0)); break;
+ case el::Color::Default: default: SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | (bright ? FOREGROUND_INTENSITY:0)); break;
+ }
+#else
+ if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput))
+ {
+ switch (color)
+ {
+ case el::Color::Red: ELPP_COUT << (bright ? "\033[1;31m" : "\033[0;31m"); break;
+ case el::Color::Green: ELPP_COUT << (bright ? "\033[1;32m" : "\033[0;32m"); break;
+ case el::Color::Yellow: ELPP_COUT << (bright ? "\033[1;33m" : "\033[0;33m"); break;
+ case el::Color::Blue: ELPP_COUT << (bright ? "\033[1;34m" : "\033[0;34m"); break;
+ case el::Color::Magenta: ELPP_COUT << (bright ? "\033[1;35m" : "\033[0;35m"); break;
+ case el::Color::Cyan: ELPP_COUT << (bright ? "\033[1;36m" : "\033[0;36m"); break;
+ case el::Color::Default: default: ELPP_COUT << "\033[0m"; break;
+ }
+ }
+#endif
+}
+
} // namespace utils
} // namespace base
@@ -609,19 +654,34 @@ void Configurations::unsafeSetGlobally(ConfigurationType configurationType, cons
// LogBuilder
-void LogBuilder::convertToColoredOutput(base::type::string_t* logLine, Level level) {
+void LogBuilder::convertToColoredOutput(base::type::string_t* logLine, Level level, Color color) {
if (!m_termSupportsColor) return;
const base::type::char_t* resetColor = ELPP_LITERAL("\x1b[0m");
- if (level == Level::Error || level == Level::Fatal)
- *logLine = ELPP_LITERAL("\x1b[31m") + *logLine + resetColor;
- else if (level == Level::Warning)
- *logLine = ELPP_LITERAL("\x1b[33m") + *logLine + resetColor;
- else if (level == Level::Debug)
- *logLine = ELPP_LITERAL("\x1b[32m") + *logLine + resetColor;
- else if (level == Level::Info)
- *logLine = ELPP_LITERAL("\x1b[36m") + *logLine + resetColor;
- else if (level == Level::Trace)
- *logLine = ELPP_LITERAL("\x1b[35m") + *logLine + resetColor;
+ if (color == Color::Red)
+ *logLine = ELPP_LITERAL("\x1b[1;31m") + *logLine + resetColor;
+ else if (color == Color::Yellow)
+ *logLine = ELPP_LITERAL("\x1b[1;33m") + *logLine + resetColor;
+ else if (color == Color::Green)
+ *logLine = ELPP_LITERAL("\x1b[1;32m") + *logLine + resetColor;
+ else if (color == Color::Cyan)
+ *logLine = ELPP_LITERAL("\x1b[1;36m") + *logLine + resetColor;
+ else if (color == Color::Magenta)
+ *logLine = ELPP_LITERAL("\x1b[1;35m") + *logLine + resetColor;
+ else if (color == Color::Blue)
+ *logLine = ELPP_LITERAL("\x1b[1;34m") + *logLine + resetColor;
+ else if (color == Color::Default)
+ {
+ if (level == Level::Error || level == Level::Fatal)
+ *logLine = ELPP_LITERAL("\x1b[31m") + *logLine + resetColor;
+ else if (level == Level::Warning)
+ *logLine = ELPP_LITERAL("\x1b[33m") + *logLine + resetColor;
+ else if (level == Level::Debug)
+ *logLine = ELPP_LITERAL("\x1b[32m") + *logLine + resetColor;
+ else if (level == Level::Info)
+ *logLine = ELPP_LITERAL("\x1b[36m") + *logLine + resetColor;
+ else if (level == Level::Trace)
+ *logLine = ELPP_LITERAL("\x1b[35m") + *logLine + resetColor;
+ }
}
// Logger
@@ -2372,13 +2432,32 @@ void DefaultLogDispatchCallback::handle(const LogDispatchData* data) {
m_data = data;
base::TypedConfigurations* tc = m_data->logMessage()->logger()->typedConfigurations();
const base::LogFormat* logFormat = &tc->logFormat(m_data->logMessage()->level());
- dispatch(base::utils::DateTime::getDateTime(logFormat->dateTimeFormat().c_str(), &tc->subsecondPrecision(m_data->logMessage()->level()))
- + "\t" + convertToChar(m_data->logMessage()->level()) + " " + m_data->logMessage()->message() + "\n",
- m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
- m_data->dispatchAction() == base::DispatchAction::NormalLog || m_data->dispatchAction() == base::DispatchAction::FileOnlyLog));
+
+ const auto &logmsg = m_data->logMessage();
+ const auto msg = logmsg->message();
+ if (strchr(msg.c_str(), '\n'))
+ {
+ std::vector<std::string> v;
+ boost::split(v, msg, boost::is_any_of("\n"));
+ for (const std::string &s: v)
+ {
+ LogMessage msgline(logmsg->level(), logmsg->color(), logmsg->file(), logmsg->line(), logmsg->func(), logmsg->verboseLevel(), logmsg->logger(), &s);
+ dispatch(base::utils::DateTime::getDateTime(logFormat->dateTimeFormat().c_str(), &tc->subsecondPrecision(m_data->logMessage()->level())) + "\t" + convertToChar(m_data->logMessage()->level()) + " ",
+ s + "\n",
+ m_data->logMessage()->logger()->logBuilder()->build(&msgline,
+ m_data->dispatchAction() == base::DispatchAction::NormalLog || m_data->dispatchAction() == base::DispatchAction::FileOnlyLog));
+ }
+ }
+ else
+ {
+ dispatch(base::utils::DateTime::getDateTime(logFormat->dateTimeFormat().c_str(), &tc->subsecondPrecision(m_data->logMessage()->level()))
+ + "\t" + convertToChar(m_data->logMessage()->level()) + " ", m_data->logMessage()->message() + "\n",
+ m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
+ m_data->dispatchAction() == base::DispatchAction::NormalLog || m_data->dispatchAction() == base::DispatchAction::FileOnlyLog));
+ }
}
-void DefaultLogDispatchCallback::dispatch(base::type::string_t&& rawLine, base::type::string_t&& logLine) {
+void DefaultLogDispatchCallback::dispatch(base::type::string_t&& rawLinePrefix, base::type::string_t&& rawLinePayload, base::type::string_t&& logLine) {
if (m_data->dispatchAction() == base::DispatchAction::NormalLog || m_data->dispatchAction() == base::DispatchAction::FileOnlyLog) {
if (m_data->logMessage()->logger()->m_typedConfigurations->toFile(m_data->logMessage()->level())) {
base::type::fstream_t* fs = m_data->logMessage()->logger()->m_typedConfigurations->fileStream(
@@ -2404,9 +2483,14 @@ void DefaultLogDispatchCallback::dispatch(base::type::string_t&& rawLine, base::
}
if (m_data->dispatchAction() != base::DispatchAction::FileOnlyLog) {
if (m_data->logMessage()->logger()->m_typedConfigurations->toStandardOutput(m_data->logMessage()->level())) {
- if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput))
- m_data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&rawLine, m_data->logMessage()->level());
- ELPP_COUT << ELPP_COUT_LINE(rawLine);
+ const el::Level level = m_data->logMessage()->level();
+ const el::Color color = m_data->logMessage()->color();
+ el::base::utils::setConsoleColor(el::base::utils::colorFromLevel(level), false);
+ ELPP_COUT << rawLinePrefix;
+ el::base::utils::setConsoleColor(color == el::Color::Default ? el::base::utils::colorFromLevel(level): color, color != el::Color::Default);
+ ELPP_COUT << rawLinePayload;
+ el::base::utils::setConsoleColor(el::Color::Default, false);
+ ELPP_COUT << std::flush;
}
}
}
@@ -2447,7 +2531,7 @@ void AsyncLogDispatchCallback::handle(const LogDispatchData* data) {
if ((data->dispatchAction() == base::DispatchAction::NormalLog || data->dispatchAction() == base::DispatchAction::FileOnlyLog)
&& data->logMessage()->logger()->typedConfigurations()->toStandardOutput(data->logMessage()->level())) {
if (ELPP->hasFlag(LoggingFlag::ColoredTerminalOutput))
- data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, data->logMessage()->level());
+ data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, data->logMessage()->level(), data->logMessage()->color());
ELPP_COUT << ELPP_COUT_LINE(logLine);
}
// Save resources and only queue if we want to write to file otherwise just ignore handler
@@ -2739,7 +2823,7 @@ void Writer::initializeLogger(const std::string& loggerId, bool lookup, bool nee
ELPP->registeredLoggers()->get(std::string(base::consts::kDefaultLoggerId));
}
}
- Writer(Level::Debug, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
+ Writer(Level::Debug, Color::Default, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
<< "Logger [" << loggerId << "] is not registered yet!";
m_proceed = false;
} else {
@@ -2813,7 +2897,7 @@ void Writer::processDispatch() {
void Writer::triggerDispatch(void) {
if (m_proceed) {
if (m_msg == nullptr) {
- LogMessage msg(m_level, m_file, m_line, m_func, m_verboseLevel,
+ LogMessage msg(m_level, m_color, m_file, m_line, m_func, m_verboseLevel,
m_logger);
base::LogDispatcher(m_proceed, &msg, m_dispatchAction).dispatch();
} else {
@@ -2826,7 +2910,7 @@ void Writer::triggerDispatch(void) {
}
if (m_proceed && m_level == Level::Fatal
&& !ELPP->hasFlag(LoggingFlag::DisableApplicationAbortOnFatalLog)) {
- base::Writer(Level::Warning, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
+ base::Writer(Level::Warning, Color::Default, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
<< "Aborting application. Reason: Fatal log at [" << m_file << ":" << m_line << "]";
std::stringstream reasonStream;
reasonStream << "Fatal log at [" << m_file << ":" << m_line << "]"