diff --git a/include/spdlog/common.h b/include/spdlog/common.h index a0a227ef..4e85aa2b 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -62,6 +62,27 @@ using level_t = std::atomic; using log_err_handler = std::function; +namespace color +{ +typedef enum +{ + grey = 0, + red = 1, + green = 2, + yellow = 3, + blue = 4, + magenta = 5, + cyan = 6, + white = 7, + light_red = 8, + light_green = 9, + light_yellow = 10, + light_blue = 11, + light_magenta = 12, + light_cyan = 13 +}color_enum; +} + //Log level enum namespace level { diff --git a/include/spdlog/details/logger_impl.h b/include/spdlog/details/logger_impl.h index 2b27f105..2f411186 100644 --- a/include/spdlog/details/logger_impl.h +++ b/include/spdlog/details/logger_impl.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -100,6 +101,26 @@ inline void spdlog::logger::log(level::level_enum lvl, const char* msg) } +template +inline void spdlog::logger::color(level::level_enum lvl, color::color_enum color, const char* msg) +{ + if (!should_log(lvl)) return; + try + { + details::log_msg log_msg(&_name, lvl); + log_msg.raw << msg; + _sink_it(log_msg, color); + } + catch (const std::exception &ex) + { + _err_handler(ex.what()); + } + catch (...) + { + _err_handler("Unknown exception"); + } +} + template inline void spdlog::logger::log(level::level_enum lvl, const T& msg) { @@ -257,6 +278,21 @@ inline void spdlog::logger::_sink_it(details::log_msg& msg) flush(); } +inline void spdlog::logger::_sink_it(details::log_msg& msg, color::color_enum color) +{ + _formatter->format(msg); + for (auto &sink : _sinks) + { + if( sink->should_log( msg.level)) + { + std::static_pointer_cast(sink)->log_color(msg, color); + } + } + + if(_should_flush_on(msg)) + flush(); +} + inline void spdlog::logger::_set_pattern(const std::string& pattern) { _formatter = std::make_shared(pattern); diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index a2deb51d..09147bca 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -37,6 +37,7 @@ public: template void log(level::level_enum lvl, const char* fmt, const Args&... args); template void log(level::level_enum lvl, const char* msg); + template void color(level::level_enum lvl, color::color_enum color, const char* msg); template void trace(const char* fmt, const Args&... args); template void debug(const char* fmt, const Args&... args); template void info(const char* fmt, const Args&... args); diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index 96e10148..5bf4c51f 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -33,6 +33,8 @@ public: virtual void log(const details::log_msg& msg) override; virtual void flush() override; + inline void log_color(const details::log_msg& msg, color::color_enum color); + void set_color(level::level_enum color_level, const std::string& color); /// Formatting codes @@ -54,6 +56,15 @@ public: const std::string cyan = "\033[36m"; const std::string white = "\033[37m"; + //Light Colors + const std::string light_red = "\033[1;31m"; + const std::string light_green = "\033[1;32m"; + const std::string light_yellow = "\033[1;33m"; + const std::string light_blue = "\033[1;34m"; + const std::string light_magenta = "\033[1;35m"; + const std::string light_cyan = "\033[1;36m"; + const std::string light_white = "\033[1;37m"; + /// Background colors const std::string on_grey = "\033[40m"; const std::string on_red = "\033[41m"; @@ -81,6 +92,52 @@ inline ansicolor_sink::ansicolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sin colors_[level::off] = reset; } +inline void ansicolor_sink::log_color(const details::log_msg& msg, color::color_enum color) +{ + std::string prefix; + switch (color) { + case color::color_enum::grey : + prefix = grey; break; + case color::color_enum::red : + prefix = red; break; + case color::color_enum::green : + prefix = green; break; + case color::color_enum::yellow : + prefix = yellow; break; + case color::color_enum::blue : + prefix = blue; break; + case color::color_enum::magenta : + prefix = magenta; break; + case color::color_enum::cyan : + prefix = cyan; break; + case color::color_enum::white : + prefix = white; break; + case color::color_enum::light_red : + prefix = light_red; break; + case color::color_enum::light_green : + prefix = light_green; break; + case color::color_enum::light_yellow : + prefix = light_yellow; break; + case color::color_enum::light_blue : + prefix = light_blue; break; + case color::color_enum::light_magenta : + prefix = light_magenta; break; + case color::color_enum::light_cyan : + prefix = light_cyan; break; + default: + prefix = reset; + } + const std::string& s = msg.formatted.str(); + const std::string& suffix = reset; + details::log_msg m; + m.level = msg.level; + m.logger_name = msg.logger_name; + m.time = msg.time; + m.thread_id = msg.thread_id; + m.formatted << prefix << s << suffix; + sink_->log(m); +} + inline void ansicolor_sink::log(const details::log_msg& msg) { // Wrap the originally formatted message in color codes