mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-12 02:23:14 +00:00
Merge pull request #9294 from ClickHouse/colors-in-logs-sent-to-client
Colors in logs sent to client
This commit is contained in:
commit
66e7965381
@ -16,6 +16,7 @@ set (SRCS
|
||||
setTerminalEcho.cpp
|
||||
shift10.cpp
|
||||
sleep.cpp
|
||||
terminalColors.cpp
|
||||
)
|
||||
|
||||
if (ENABLE_REPLXX)
|
||||
|
49
base/common/terminalColors.cpp
Normal file
49
base/common/terminalColors.cpp
Normal 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";
|
||||
}
|
15
base/common/terminalColors.h
Normal file
15
base/common/terminalColors.h
Normal 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();
|
@ -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_)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user