Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colors in logs sent to client #9294

Merged
merged 2 commits into from
Feb 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions base/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ set (SRCS
setTerminalEcho.cpp
shift10.cpp
sleep.cpp
terminalColors.cpp
)

if (ENABLE_REPLXX)
Expand Down
49 changes: 49 additions & 0 deletions base/common/terminalColors.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <string>
#include <common/terminalColors.h>


std::string setColor(UInt64 hash)
{
/// Make a random RGB color that has constant brightness.
/// https://en.wikipedia.org/wiki/YCbCr

/// Note that this is darker than the middle relative luminance, see "Gamma_correction" and "Luma_(video)".
/// It still looks awesome.
UInt8 y = 128;

UInt8 cb = hash % 256;
UInt8 cr = hash / 256 % 256;

UInt8 r = std::max(0.0, std::min(255.0, y + 1.402 * (cr - 128)));
UInt8 g = std::max(0.0, std::min(255.0, y - 0.344136 * (cb - 128) - 0.714136 * (cr - 128)));
UInt8 b = std::max(0.0, std::min(255.0, y + 1.772 * (cb - 128)));

/// ANSI escape sequence to set 24-bit foreground font color in terminal.
return "\033[38;2;" + std::to_string(r) + ";" + std::to_string(g) + ";" + std::to_string(b) + "m";
}

const char * setColorForLogPriority(int priority)
{
if (priority < 1 || priority > 8)
return "";

static const char * colors[] =
{
"",
"\033[1;41m", /// Fatal
"\033[7;31m", /// Critical
"\033[1;31m", /// Error
"\033[0;31m", /// Warning
"\033[0;33m", /// Notice
"\033[1m", /// Information
"", /// Debug
"\033[2m", /// Trace
};

return colors[priority];
}

const char * resetColor()
{
return "\033[0m";
}
15 changes: 15 additions & 0 deletions base/common/terminalColors.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <string>
#include <common/Types.h>


/** Set color in terminal based on 64-bit hash value.
* It can be used to choose some random color deterministically based on some other value.
* Hash value should be uniformly distributed.
*/
std::string setColor(UInt64 hash);

/** Set color for logger priority value. */
const char * setColorForLogPriority(int priority);

/** Undo changes made by the functions above. */
const char * resetColor();
7 changes: 4 additions & 3 deletions base/loggers/loggers/Loggers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,13 @@ void Loggers::buildLoggers(Poco::Util::AbstractConfiguration & config, Poco::Log
split->addChannel(log);
}

bool is_tty = isatty(STDIN_FILENO) || isatty(STDERR_FILENO);
bool should_log_to_console = isatty(STDIN_FILENO) || isatty(STDERR_FILENO);
bool color_logs_by_default = isatty(STDERR_FILENO);

if (config.getBool("logger.console", false)
|| (!config.hasProperty("logger.console") && !is_daemon && is_tty))
|| (!config.hasProperty("logger.console") && !is_daemon && should_log_to_console))
{
bool color_enabled = config.getBool("logger.color_terminal", true) && is_tty;
bool color_enabled = config.getBool("logger.color_terminal", color_logs_by_default);

Poco::AutoPtr<OwnPatternFormatter> pf = new OwnPatternFormatter(this, OwnPatternFormatter::ADD_NOTHING, color_enabled);
Poco::AutoPtr<DB::OwnFormattingChannel> log = new DB::OwnFormattingChannel(pf, new Poco::ConsoleChannel);
Expand Down
49 changes: 1 addition & 48 deletions base/loggers/loggers/OwnPatternFormatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,57 +9,10 @@
#include <Interpreters/InternalTextLogsQueue.h>
#include <Common/CurrentThread.h>
#include <common/getThreadId.h>
#include <common/terminalColors.h>
#include "Loggers.h"


static std::string setColor(UInt64 num)
{
/// Make a random RGB color that has constant brightness.
/// https://en.wikipedia.org/wiki/YCbCr

/// Note that this is darker than the middle relative luminance, see "Gamma_correction" and "Luma_(video)".
/// It still looks awesome.
UInt8 y = 128;

UInt8 cb = num % 256;
UInt8 cr = num / 256 % 256;

UInt8 r = std::max(0.0, std::min(255.0, y + 1.402 * (cr - 128)));
UInt8 g = std::max(0.0, std::min(255.0, y - 0.344136 * (cb - 128) - 0.714136 * (cr - 128)));
UInt8 b = std::max(0.0, std::min(255.0, y + 1.772 * (cb - 128)));

/// ANSI escape sequence to set 24-bit foreground font color in terminal.
return "\033[38;2;" + DB::toString(r) + ";" + DB::toString(g) + ";" + DB::toString(b) + "m";
}

static const char * setColorForLogPriority(int priority)
{
if (priority < 1 || priority > 8)
return "";

static const char * colors[] =
{
"",
"\033[1;41m", /// Fatal
"\033[7;31m", /// Critical
"\033[1;31m", /// Error
"\033[0;31m", /// Warning
"\033[0;33m", /// Notice
"\033[1m", /// Information
"", /// Debug
"\033[2m", /// Trace
};

return colors[priority];
}

static const char * resetColor()
{
return "\033[0m";
}



OwnPatternFormatter::OwnPatternFormatter(const Loggers * loggers_, OwnPatternFormatter::Options options_, bool color_)
: Poco::PatternFormatter(""), loggers(loggers_), options(options_), color(color_)
{
Expand Down
14 changes: 8 additions & 6 deletions dbms/programs/client/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ class Client : public Poco::Util::Application
bool echo_queries = false; /// Print queries before execution in batch mode.
bool ignore_error = false; /// In case of errors, don't print error message, continue to next query. Only applicable for non-interactive mode.
bool print_time_to_stderr = false; /// Output execution time to stderr in batch mode.
bool stdin_is_not_tty = false; /// stdin is not a terminal.
bool stdin_is_a_tty = false; /// stdin is a terminal.
bool stdout_is_a_tty = false; /// stdout is a terminal.

uint16_t terminal_width = 0; /// Terminal width is needed to render progress bar.

Expand Down Expand Up @@ -378,7 +379,7 @@ class Client : public Poco::Util::Application
/// The value of the option is used as the text of query (or of multiple queries).
/// If stdin is not a terminal, INSERT data for the first query is read from it.
/// - stdin is not a terminal. In this case queries are read from it.
if (stdin_is_not_tty || config().has("query"))
if (!stdin_is_a_tty || config().has("query"))
is_interactive = false;

std::cout << std::fixed << std::setprecision(3);
Expand Down Expand Up @@ -910,7 +911,7 @@ class Client : public Poco::Util::Application
? query.substr(0, parsed_insert_query.data - query.data())
: query;

if (!parsed_insert_query.data && (is_interactive || (stdin_is_not_tty && std_in.eof())))
if (!parsed_insert_query.data && (is_interactive || (!stdin_is_a_tty && std_in.eof())))
throw Exception("No data to insert", ErrorCodes::NO_DATA_TO_INSERT);

connection->sendQuery(connection_parameters.timeouts, query_without_data, query_id, QueryProcessingStage::Complete, &context.getSettingsRef(), nullptr, true);
Expand Down Expand Up @@ -1332,7 +1333,7 @@ class Client : public Poco::Util::Application
}
}

logs_out_stream = std::make_shared<InternalTextLogsRowOutputStream>(*wb);
logs_out_stream = std::make_shared<InternalTextLogsRowOutputStream>(*wb, stdout_is_a_tty);
logs_out_stream->writePrefix();
}
}
Expand Down Expand Up @@ -1643,9 +1644,10 @@ class Client : public Poco::Util::Application
}
}

stdin_is_not_tty = !isatty(STDIN_FILENO);
stdin_is_a_tty = isatty(STDIN_FILENO);
stdout_is_a_tty = isatty(STDOUT_FILENO);

if (!stdin_is_not_tty)
if (stdin_is_a_tty)
terminal_width = getTerminalWidth();

namespace po = boost::program_options;
Expand Down
29 changes: 24 additions & 5 deletions dbms/src/DataStreams/InternalTextLogsRowOutputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
#include <Core/Block.h>
#include <Interpreters/InternalTextLogsQueue.h>
#include <Common/typeid_cast.h>
#include <Common/HashTable/Hash.h>
#include <DataTypes/IDataType.h>
#include <Columns/ColumnsNumber.h>
#include <Columns/ColumnString.h>
#include <IO/WriteHelpers.h>
#include <common/terminalColors.h>


namespace DB
Expand Down Expand Up @@ -35,7 +37,11 @@ void InternalTextLogsRowOutputStream::write(const Block & block)
if (host_name.size)
{
writeCString("[", wb);
if (color)
writeString(setColor(StringRefHash()(host_name)), wb);
writeString(host_name, wb);
if (color)
writeCString(resetColor(), wb);
writeCString("] ", wb);
}

Expand All @@ -51,21 +57,34 @@ void InternalTextLogsRowOutputStream::write(const Block & block)
writeChar('0' + ((microseconds / 10) % 10), wb);
writeChar('0' + ((microseconds / 1) % 10), wb);

UInt64 thread_id = array_thread_id[row_num];
writeCString(" [ ", wb);
if (color)
writeString(setColor(intHash64(thread_id)), wb);
writeIntText(thread_id, wb);
if (color)
writeCString(resetColor(), wb);
writeCString(" ]", wb);

auto query_id = column_query_id.getDataAt(row_num);
if (query_id.size)
{
writeCString(" {", wb);
if (color)
writeString(setColor(StringRefHash()(query_id)), wb);
writeString(query_id, wb);
if (color)
writeCString(resetColor(), wb);
writeCString("}", wb);
}

UInt64 thread_id = array_thread_id[row_num];
writeCString(" [ ", wb);
writeIntText(thread_id, wb);
writeCString(" ] <", wb);

Int8 priority = array_priority[row_num];
writeCString(" <", wb);
if (color)
writeCString(setColorForLogPriority(priority), wb);
writeString(InternalTextLogsQueue::getPriorityName(priority), wb);
if (color)
writeCString(resetColor(), wb);
writeCString("> ", wb);

auto source = column_source.getDataAt(row_num);
Expand Down
5 changes: 2 additions & 3 deletions dbms/src/DataStreams/InternalTextLogsRowOutputStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ namespace DB
class InternalTextLogsRowOutputStream : public IBlockOutputStream
{
public:

InternalTextLogsRowOutputStream(WriteBuffer & buf_out) : wb(buf_out) {}
InternalTextLogsRowOutputStream(WriteBuffer & buf_out, bool color_) : wb(buf_out), color(color_) {}

Block getHeader() const override;

Expand All @@ -25,8 +24,8 @@ class InternalTextLogsRowOutputStream : public IBlockOutputStream
}

private:

WriteBuffer & wb;
bool color;
};

}