Merge pull request #9294 from ClickHouse/colors-in-logs-sent-to-client

Colors in logs sent to client
This commit is contained in:
alexey-milovidov 2020-02-22 02:24:08 +03:00 committed by GitHub
commit 66e7965381
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 100 additions and 62 deletions

View File

@ -16,6 +16,7 @@ set (SRCS
setTerminalEcho.cpp
shift10.cpp
sleep.cpp
terminalColors.cpp
)
if (ENABLE_REPLXX)

View File

@ -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";
}

View File

@ -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();

View File

@ -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_)
{

View File

@ -130,7 +130,8 @@ private:
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.
@ -378,7 +379,7 @@ private:
/// 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);
@ -910,7 +911,7 @@ private:
? 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);
@ -1332,7 +1333,7 @@ private:
}
}
logs_out_stream = std::make_shared<InternalTextLogsRowOutputStream>(*wb);
logs_out_stream = std::make_shared<InternalTextLogsRowOutputStream>(*wb, stdout_is_a_tty);
logs_out_stream->writePrefix();
}
}
@ -1643,9 +1644,10 @@ public:
}
}
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;

View File

@ -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
@ -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);
}
@ -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);

View File

@ -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;
@ -25,8 +24,8 @@ public:
}
private:
WriteBuffer & wb;
bool color;
};
}