From f1e3f676e3b090def505234b44ed304b6d5b9a6c Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Wed, 13 Apr 2016 01:12:22 -0400 Subject: [PATCH 01/10] ansiocolor_sink now works correctly on windows --- include/spdlog/sinks/ansicolor_sink.h | 73 +++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index aa4b93bf..674ddfeb 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -33,6 +33,40 @@ public: virtual void log(const details::log_msg& msg) override; virtual void flush() override; +#ifdef _WIN32 + void set_color(level::level_enum level, const short& color); + + /// Formatting codes + const short reset = 0; + const short bold = FOREGROUND_INTENSITY; + const short dark = reset; // Not implemented in windows + const short underline = reset; // Not implemented in windows + const short blink = reset; // Not implemented in windows + const short reverse = FOREGROUND_RED | FOREGROUND_GREEN | + FOREGROUND_BLUE | BACKGROUND_RED | + BACKGROUND_GREEN | BACKGROUND_BLUE; // XOR to use this + const short concealed = reset; // Not implemented in windows + + // Foreground colors + const short grey = bold; + const short red = FOREGROUND_RED; + const short green = FOREGROUND_GREEN; + const short yellow = FOREGROUND_RED | FOREGROUND_GREEN; + const short blue = FOREGROUND_BLUE; + const short magenta = FOREGROUND_RED | FOREGROUND_BLUE; + const short cyan = FOREGROUND_GREEN | FOREGROUND_BLUE; + const short white = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + + /// Background colors + const short on_grey = BACKGROUND_INTENSITY; + const short on_red = BACKGROUND_RED; + const short on_green = BACKGROUND_GREEN; + const short on_yellow = BACKGROUND_RED | BACKGROUND_GREEN; + const short on_blue = BACKGROUND_BLUE; + const short on_magenta = BACKGROUND_RED | BACKGROUND_BLUE; + const short on_cyan = BACKGROUND_GREEN | BACKGROUND_BLUE; + const short on_white = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; +#else void set_color(level::level_enum level, const std::string& color); /// Formatting codes @@ -63,15 +97,31 @@ public: const std::string on_magenta = "\033[45m"; const std::string on_cyan = "\033[46m"; const std::string on_white = "\033[47m"; - +#endif protected: sink_ptr sink_; +#ifdef _WIN32 + std::map colors_; +#else std::map colors_; +#endif }; inline ansicolor_sink::ansicolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) { +#ifdef _WIN32 + colors_[level::trace] = cyan; + colors_[level::debug] = cyan; + colors_[level::info] = white; + colors_[level::notice] = bold | white; + colors_[level::warn] = bold | yellow; + colors_[level::err] = red; + colors_[level::critical] = bold | red; + colors_[level::alert] = bold | white | on_red; + colors_[level::emerg] = bold | yellow | on_red; + colors_[level::off] = reset; +#else colors_[level::trace] = cyan; colors_[level::debug] = cyan; colors_[level::info] = white; @@ -82,25 +132,38 @@ inline ansicolor_sink::ansicolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sin colors_[level::alert] = bold + white + on_red; colors_[level::emerg] = bold + yellow + on_red; colors_[level::off] = reset; +#endif } inline void ansicolor_sink::log(const details::log_msg& msg) { // Wrap the originally formatted message in color codes - const std::string& prefix = colors_[msg.level]; const std::string& s = msg.formatted.str(); - const std::string& suffix = reset; details::log_msg m; +#ifdef _WIN32 + m.formatted << s; + + SetConsoleTextAttribute(GetStdHandle( STD_OUTPUT_HANDLE ), colors_[msg.level]); + sink_->log( m ); + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), reset ); +#else + const std::string& prefix = colors_[msg.level]; + const std::string& suffix = reset; m.formatted << prefix << s << suffix; - sink_->log(m); + + sink_->log( m ); +#endif } inline void ansicolor_sink::flush() { sink_->flush(); } - +#ifdef _WIN32 +inline void ansicolor_sink::set_color(level::level_enum level, const short& color) +#else inline void ansicolor_sink::set_color(level::level_enum level, const std::string& color) +#endif { colors_[level] = color; } From 6d0d26b31955a751d732561b5878bd3e36a33cea Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Wed, 13 Apr 2016 10:33:49 -0400 Subject: [PATCH 02/10] Update ansicolor_sink.h Moved level colors that didn't change on either OS out of the #ifdefs --- include/spdlog/sinks/ansicolor_sink.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index 674ddfeb..1b760686 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -110,28 +110,24 @@ protected: inline ansicolor_sink::ansicolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) { -#ifdef _WIN32 colors_[level::trace] = cyan; colors_[level::debug] = cyan; colors_[level::info] = white; + colors_[level::err] = red; + colors_[level::off] = reset; + +#ifdef _WIN32 colors_[level::notice] = bold | white; colors_[level::warn] = bold | yellow; - colors_[level::err] = red; colors_[level::critical] = bold | red; colors_[level::alert] = bold | white | on_red; colors_[level::emerg] = bold | yellow | on_red; - colors_[level::off] = reset; #else - colors_[level::trace] = cyan; - colors_[level::debug] = cyan; - colors_[level::info] = white; colors_[level::notice] = bold + white; colors_[level::warn] = bold + yellow; - colors_[level::err] = red; colors_[level::critical] = bold + red; colors_[level::alert] = bold + white + on_red; colors_[level::emerg] = bold + yellow + on_red; - colors_[level::off] = reset; #endif } From ceab2656a1f23f93b190a73bee1f5751a8a7da5b Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 11:20:18 -0400 Subject: [PATCH 03/10] Undo changes for windows colors --- include/spdlog/sinks/ansicolor_sink.h | 72 +++------------------------ 1 file changed, 6 insertions(+), 66 deletions(-) diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index 1b760686..6f2a690b 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -33,40 +33,6 @@ public: virtual void log(const details::log_msg& msg) override; virtual void flush() override; -#ifdef _WIN32 - void set_color(level::level_enum level, const short& color); - - /// Formatting codes - const short reset = 0; - const short bold = FOREGROUND_INTENSITY; - const short dark = reset; // Not implemented in windows - const short underline = reset; // Not implemented in windows - const short blink = reset; // Not implemented in windows - const short reverse = FOREGROUND_RED | FOREGROUND_GREEN | - FOREGROUND_BLUE | BACKGROUND_RED | - BACKGROUND_GREEN | BACKGROUND_BLUE; // XOR to use this - const short concealed = reset; // Not implemented in windows - - // Foreground colors - const short grey = bold; - const short red = FOREGROUND_RED; - const short green = FOREGROUND_GREEN; - const short yellow = FOREGROUND_RED | FOREGROUND_GREEN; - const short blue = FOREGROUND_BLUE; - const short magenta = FOREGROUND_RED | FOREGROUND_BLUE; - const short cyan = FOREGROUND_GREEN | FOREGROUND_BLUE; - const short white = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - - /// Background colors - const short on_grey = BACKGROUND_INTENSITY; - const short on_red = BACKGROUND_RED; - const short on_green = BACKGROUND_GREEN; - const short on_yellow = BACKGROUND_RED | BACKGROUND_GREEN; - const short on_blue = BACKGROUND_BLUE; - const short on_magenta = BACKGROUND_RED | BACKGROUND_BLUE; - const short on_cyan = BACKGROUND_GREEN | BACKGROUND_BLUE; - const short on_white = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; -#else void set_color(level::level_enum level, const std::string& color); /// Formatting codes @@ -97,15 +63,10 @@ public: const std::string on_magenta = "\033[45m"; const std::string on_cyan = "\033[46m"; const std::string on_white = "\033[47m"; -#endif protected: sink_ptr sink_; -#ifdef _WIN32 - std::map colors_; -#else std::map colors_; -#endif }; inline ansicolor_sink::ansicolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) @@ -113,53 +74,32 @@ inline ansicolor_sink::ansicolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sin colors_[level::trace] = cyan; colors_[level::debug] = cyan; colors_[level::info] = white; - colors_[level::err] = red; - colors_[level::off] = reset; - -#ifdef _WIN32 - colors_[level::notice] = bold | white; - colors_[level::warn] = bold | yellow; - colors_[level::critical] = bold | red; - colors_[level::alert] = bold | white | on_red; - colors_[level::emerg] = bold | yellow | on_red; -#else colors_[level::notice] = bold + white; colors_[level::warn] = bold + yellow; + colors_[level::err] = red; colors_[level::critical] = bold + red; colors_[level::alert] = bold + white + on_red; colors_[level::emerg] = bold + yellow + on_red; -#endif + colors_[level::off] = reset; } inline void ansicolor_sink::log(const details::log_msg& msg) { // Wrap the originally formatted message in color codes - const std::string& s = msg.formatted.str(); - details::log_msg m; -#ifdef _WIN32 - m.formatted << s; - - SetConsoleTextAttribute(GetStdHandle( STD_OUTPUT_HANDLE ), colors_[msg.level]); - sink_->log( m ); - SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), reset ); -#else const std::string& prefix = colors_[msg.level]; + const std::string& s = msg.formatted.str(); const std::string& suffix = reset; + details::log_msg m; m.formatted << prefix << s << suffix; - - sink_->log( m ); -#endif + sink_->log(m); } inline void ansicolor_sink::flush() { sink_->flush(); } -#ifdef _WIN32 -inline void ansicolor_sink::set_color(level::level_enum level, const short& color) -#else + inline void ansicolor_sink::set_color(level::level_enum level, const std::string& color) -#endif { colors_[level] = color; } From 85af236085a65116a8c9f8f3040f976e57028a28 Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 11:21:32 -0400 Subject: [PATCH 04/10] Created wincolor_sink --- include/spdlog/sinks/wincolor_sink.h | 136 +++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 include/spdlog/sinks/wincolor_sink.h diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h new file mode 100644 index 00000000..55dbca18 --- /dev/null +++ b/include/spdlog/sinks/wincolor_sink.h @@ -0,0 +1,136 @@ +// +// Copyright(c) 2016 Christopher J. Torres (a modified verison of ansicolor_sink). +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +#pragma once + +#include +#include + +#include +#include + +namespace spdlog +{ +namespace sinks +{ + +#ifndef _WIN32 +#define FOREGROUND_INTENSITY 0 +#define FOREGROUND_RED 0 +#define FOREGROUND_GREEN 0 +#define FOREGROUND_BLUE 0 +#define BACKGROUND_RED 0 +#define BACKGROUND_GREEN 0 +#define BACKGROUND_BLUE 0 +#endif + +/** + * @brief The wincolor_sink is a decorator around another sink and uses + * the windows api to set the color depending on the severity + * of the message. + */ +class wincolor_sink : public sink +{ +public: + wincolor_sink(sink_ptr wrapped_sink); + virtual ~wincolor_sink(); + + wincolor_sink(const wincolor_sink& other) = delete; + wincolor_sink& operator=(const wincolor_sink& other) = delete; + + virtual void log(const details::log_msg& msg) override; + virtual void flush() override; + + // Formatting codes + const short reset = 0; + const short bold = FOREGROUND_INTENSITY; + const short dark = reset; // Not implemented in windows + const short underline = reset; // Not implemented in windows + const short blink = reset; // Not implemented in windows + const short reverse = FOREGROUND_RED | FOREGROUND_GREEN | + FOREGROUND_BLUE | BACKGROUND_RED | + BACKGROUND_GREEN | BACKGROUND_BLUE; // XOR to use this + const short concealed = reset; // Not implemented in windows + + // Foreground colors + const short grey = bold; + const short red = FOREGROUND_RED; + const short green = FOREGROUND_GREEN; + const short yellow = FOREGROUND_RED | FOREGROUND_GREEN; + const short blue = FOREGROUND_BLUE; + const short magenta = FOREGROUND_RED | FOREGROUND_BLUE; + const short cyan = FOREGROUND_GREEN | FOREGROUND_BLUE; + const short white = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + + /// Background colors + const short on_grey = BACKGROUND_INTENSITY; + const short on_red = BACKGROUND_RED; + const short on_green = BACKGROUND_GREEN; + const short on_yellow = BACKGROUND_RED | BACKGROUND_GREEN; + const short on_blue = BACKGROUND_BLUE; + const short on_magenta = BACKGROUND_RED | BACKGROUND_BLUE; + const short on_cyan = BACKGROUND_GREEN | BACKGROUND_BLUE; + const short on_white = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; + + void set_color(level::level_enum level, const short& color); + sink_ptr& wrapped_sink(); + +protected: + sink_ptr sink_; + std::map colors_; +}; + +inline wincolor_sink::wincolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) +{ + colors_[level::trace] = cyan; + colors_[level::debug] = cyan; + colors_[level::info] = white; + colors_[level::err] = red; + colors_[level::off] = reset; + + colors_[level::notice] = bold | white; + colors_[level::warn] = bold | yellow; + colors_[level::critical] = bold | red; + colors_[level::alert] = bold | white | on_red; + colors_[level::emerg] = bold | yellow | on_red; +} + +inline void wincolor_sink::log(const details::log_msg& msg) +{ + // Wrap the originally formatted message in color codes +#ifdef _WIN32 + SetConsoleTextAttribute(GetStdHandle( STD_OUTPUT_HANDLE ), colors_[msg.level]); +#endif + + sink_->log( msg ); + +#ifdef _WIN32 + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), reset ); +#endif +} + +inline void wincolor_sink::flush() +{ + sink_->flush(); +} + +inline void wincolor_sink::set_color(level::level_enum level, const short& color) +{ + colors_[level] = color; +} + +inline sink_ptr& wincolor_sink::wrapped_sink() +{ + return sink_; +} + +inline wincolor_sink::~ansicolor_sink() +{ + flush(); +} + +} // namespace sinks +} // namespace spdlog + From 97cbb875890ceb1441783e94b2bd7d93f9f4983b Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 12:03:34 -0400 Subject: [PATCH 05/10] Fixed some compile errors with wincolor_sink --- include/spdlog/sinks/wincolor_sink.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h index 55dbca18..7540e6a8 100644 --- a/include/spdlog/sinks/wincolor_sink.h +++ b/include/spdlog/sinks/wincolor_sink.h @@ -21,6 +21,7 @@ namespace sinks #define FOREGROUND_RED 0 #define FOREGROUND_GREEN 0 #define FOREGROUND_BLUE 0 +#define BACKGROUND_INTENSITY 0 #define BACKGROUND_RED 0 #define BACKGROUND_GREEN 0 #define BACKGROUND_BLUE 0 @@ -126,7 +127,7 @@ inline sink_ptr& wincolor_sink::wrapped_sink() return sink_; } -inline wincolor_sink::~ansicolor_sink() +inline wincolor_sink::~wincolor_sink() { flush(); } From 62d177be28b61736be75f4c38eea742b2617e44e Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 12:08:38 -0400 Subject: [PATCH 06/10] Handle changing the colors of STD_ERROR_HANDLE as well --- include/spdlog/sinks/wincolor_sink.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h index 7540e6a8..74870bb5 100644 --- a/include/spdlog/sinks/wincolor_sink.h +++ b/include/spdlog/sinks/wincolor_sink.h @@ -103,12 +103,14 @@ inline void wincolor_sink::log(const details::log_msg& msg) // Wrap the originally formatted message in color codes #ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle( STD_OUTPUT_HANDLE ), colors_[msg.level]); + SetConsoleTextAttribute(GetStdHandle( STD_ERROR_HANDLE ), colors_[msg.level]); #endif sink_->log( msg ); #ifdef _WIN32 - SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), reset ); + SetConsoleTextAttribute(GetStdHandle( STD_ERROR_HANDLE ), reset); + SetConsoleTextAttribute(GetStdHandle( STD_OUTPUT_HANDLE ), reset); #endif } From 3fac9ba212804b497efb04031b3ac3bb2c8f7a2c Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 12:20:36 -0400 Subject: [PATCH 07/10] create_console_logger now uses the correct color sink depending on your platform --- include/spdlog/details/spdlog_impl.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/spdlog/details/spdlog_impl.h b/include/spdlog/details/spdlog_impl.h index 10d0e685..423ec43d 100644 --- a/include/spdlog/details/spdlog_impl.h +++ b/include/spdlog/details/spdlog_impl.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -61,7 +62,11 @@ inline std::shared_ptr spdlog::daily_logger_st(const std::string inline std::shared_ptr create_console_logger(const std::string& logger_name, spdlog::sink_ptr sink, bool color) { if (color) //use color wrapper sink +#ifdef _WIN32 + sink = std::make_shared(sink); +#else sink = std::make_shared(sink); +#endif return spdlog::details::registry::instance().create(logger_name, sink); } From eafc1cc98b2cf3c0495d207f3de51db6091128e7 Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 16:19:04 -0400 Subject: [PATCH 08/10] Changed wincolor to be thread safe. --- include/spdlog/details/spdlog_impl.h | 25 ++++++++++++++++++------ include/spdlog/sinks/wincolor_sink.h | 29 +++++++++------------------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/include/spdlog/details/spdlog_impl.h b/include/spdlog/details/spdlog_impl.h index 423ec43d..0d599697 100644 --- a/include/spdlog/details/spdlog_impl.h +++ b/include/spdlog/details/spdlog_impl.h @@ -14,7 +14,9 @@ #include #include #include +#ifdef _WIN32 #include +#endif #include #include @@ -59,11 +61,22 @@ inline std::shared_ptr spdlog::daily_logger_st(const std::string } // Create stdout/stderr loggers (with optinal color support) -inline std::shared_ptr create_console_logger(const std::string& logger_name, spdlog::sink_ptr sink, bool color) +inline std::shared_ptr create_console_logger_st(const std::string& logger_name, spdlog::sink_ptr sink, bool color) +{ + if (color) //use color wrapper sink +#ifdef _WIN32 + sink = std::make_shared(sink); +#else + sink = std::make_shared(sink); +#endif + return spdlog::details::registry::instance().create(logger_name, sink); +} + +inline std::shared_ptr create_console_logger_mt(const std::string& logger_name, spdlog::sink_ptr sink, bool color) { if (color) //use color wrapper sink #ifdef _WIN32 - sink = std::make_shared(sink); + sink = std::make_shared(sink); #else sink = std::make_shared(sink); #endif @@ -72,22 +85,22 @@ inline std::shared_ptr create_console_logger(const std::string& inline std::shared_ptr spdlog::stdout_logger_mt(const std::string& logger_name, bool color) { - return create_console_logger(logger_name, sinks::stdout_sink_mt::instance(), color); + return create_console_logger_mt(logger_name, sinks::stdout_sink_mt::instance(), color); } inline std::shared_ptr spdlog::stdout_logger_st(const std::string& logger_name, bool color) { - return create_console_logger(logger_name, sinks::stdout_sink_st::instance(), color); + return create_console_logger_st(logger_name, sinks::stdout_sink_st::instance(), color); } inline std::shared_ptr spdlog::stderr_logger_mt(const std::string& logger_name, bool color) { - return create_console_logger(logger_name, sinks::stderr_sink_mt::instance(), color); + return create_console_logger_mt(logger_name, sinks::stderr_sink_mt::instance(), color); } inline std::shared_ptr spdlog::stderr_logger_st(const std::string& logger_name, bool color) { - return create_console_logger(logger_name, sinks::stderr_sink_st::instance(), color); + return create_console_logger_st(logger_name, sinks::stderr_sink_st::instance(), color); } #if defined(__linux__) || defined(__APPLE__) diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h index 74870bb5..501b2335 100644 --- a/include/spdlog/sinks/wincolor_sink.h +++ b/include/spdlog/sinks/wincolor_sink.h @@ -16,23 +16,13 @@ namespace spdlog namespace sinks { -#ifndef _WIN32 -#define FOREGROUND_INTENSITY 0 -#define FOREGROUND_RED 0 -#define FOREGROUND_GREEN 0 -#define FOREGROUND_BLUE 0 -#define BACKGROUND_INTENSITY 0 -#define BACKGROUND_RED 0 -#define BACKGROUND_GREEN 0 -#define BACKGROUND_BLUE 0 -#endif - /** * @brief The wincolor_sink is a decorator around another sink and uses * the windows api to set the color depending on the severity * of the message. */ -class wincolor_sink : public sink +template +class wincolor_sink : public base_sink { public: wincolor_sink(sink_ptr wrapped_sink); @@ -41,7 +31,6 @@ public: wincolor_sink(const wincolor_sink& other) = delete; wincolor_sink& operator=(const wincolor_sink& other) = delete; - virtual void log(const details::log_msg& msg) override; virtual void flush() override; // Formatting codes @@ -79,10 +68,16 @@ public: sink_ptr& wrapped_sink(); protected: + virtual void _sink_it(const details::log_msg& msg) override; + sink_ptr sink_; std::map colors_; }; +typedef wincolor_sink wincolor_sink_st; +typedef wincolor_sink wincolor_sink_mt; + + inline wincolor_sink::wincolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) { colors_[level::trace] = cyan; @@ -98,20 +93,14 @@ inline wincolor_sink::wincolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) colors_[level::emerg] = bold | yellow | on_red; } -inline void wincolor_sink::log(const details::log_msg& msg) +inline void wincolor_sink::_sink_it(const details::log_msg& msg) { // Wrap the originally formatted message in color codes -#ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle( STD_OUTPUT_HANDLE ), colors_[msg.level]); SetConsoleTextAttribute(GetStdHandle( STD_ERROR_HANDLE ), colors_[msg.level]); -#endif - sink_->log( msg ); - -#ifdef _WIN32 SetConsoleTextAttribute(GetStdHandle( STD_ERROR_HANDLE ), reset); SetConsoleTextAttribute(GetStdHandle( STD_OUTPUT_HANDLE ), reset); -#endif } inline void wincolor_sink::flush() From 88ebae0c445edc2f934fb1525eb7a9774714fa70 Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 18:06:51 -0400 Subject: [PATCH 09/10] Fix compile errors for Visual Studio --- include/spdlog/sinks/wincolor_sink.h | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h index 501b2335..4acff262 100644 --- a/include/spdlog/sinks/wincolor_sink.h +++ b/include/spdlog/sinks/wincolor_sink.h @@ -64,7 +64,7 @@ public: const short on_cyan = BACKGROUND_GREEN | BACKGROUND_BLUE; const short on_white = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; - void set_color(level::level_enum level, const short& color); + void set_color( level::level_enum level, const short& color ); sink_ptr& wrapped_sink(); protected: @@ -77,8 +77,8 @@ protected: typedef wincolor_sink wincolor_sink_st; typedef wincolor_sink wincolor_sink_mt; - -inline wincolor_sink::wincolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) +template +inline wincolor_sink::wincolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) { colors_[level::trace] = cyan; colors_[level::debug] = cyan; @@ -93,7 +93,8 @@ inline wincolor_sink::wincolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) colors_[level::emerg] = bold | yellow | on_red; } -inline void wincolor_sink::_sink_it(const details::log_msg& msg) +template +inline void wincolor_sink::_sink_it( const details::log_msg& msg ) { // Wrap the originally formatted message in color codes SetConsoleTextAttribute(GetStdHandle( STD_OUTPUT_HANDLE ), colors_[msg.level]); @@ -103,22 +104,26 @@ inline void wincolor_sink::_sink_it(const details::log_msg& msg) SetConsoleTextAttribute(GetStdHandle( STD_OUTPUT_HANDLE ), reset); } -inline void wincolor_sink::flush() +template +inline void wincolor_sink::flush() { sink_->flush(); } -inline void wincolor_sink::set_color(level::level_enum level, const short& color) +template +inline void wincolor_sink::set_color( level::level_enum level, const short& color ) { colors_[level] = color; } -inline sink_ptr& wincolor_sink::wrapped_sink() +template +inline sink_ptr& wincolor_sink::wrapped_sink() { return sink_; } -inline wincolor_sink::~wincolor_sink() +template +inline wincolor_sink::~wincolor_sink() { flush(); } From ca41707d9d9f4f165ce529ea928a5b9415bb7aba Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Sun, 24 Apr 2016 22:40:25 -0400 Subject: [PATCH 10/10] wincolor_sink is not a wrapper class anymore. Removed my addition to the spdlog create_console_logger function --- include/spdlog/details/spdlog_impl.h | 11 ------- include/spdlog/sinks/wincolor_sink.h | 48 +++++++++++++++++++--------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/include/spdlog/details/spdlog_impl.h b/include/spdlog/details/spdlog_impl.h index 0d599697..1414c8a8 100644 --- a/include/spdlog/details/spdlog_impl.h +++ b/include/spdlog/details/spdlog_impl.h @@ -14,9 +14,6 @@ #include #include #include -#ifdef _WIN32 -#include -#endif #include #include @@ -64,22 +61,14 @@ inline std::shared_ptr spdlog::daily_logger_st(const std::string inline std::shared_ptr create_console_logger_st(const std::string& logger_name, spdlog::sink_ptr sink, bool color) { if (color) //use color wrapper sink -#ifdef _WIN32 - sink = std::make_shared(sink); -#else sink = std::make_shared(sink); -#endif return spdlog::details::registry::instance().create(logger_name, sink); } inline std::shared_ptr create_console_logger_mt(const std::string& logger_name, spdlog::sink_ptr sink, bool color) { if (color) //use color wrapper sink -#ifdef _WIN32 - sink = std::make_shared(sink); -#else sink = std::make_shared(sink); -#endif return spdlog::details::registry::instance().create(logger_name, sink); } diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h index 4acff262..5bc744d9 100644 --- a/include/spdlog/sinks/wincolor_sink.h +++ b/include/spdlog/sinks/wincolor_sink.h @@ -25,7 +25,7 @@ template class wincolor_sink : public base_sink { public: - wincolor_sink(sink_ptr wrapped_sink); + wincolor_sink(std::ostream& os, bool force_flush=false); virtual ~wincolor_sink(); wincolor_sink(const wincolor_sink& other) = delete; @@ -34,7 +34,7 @@ public: virtual void flush() override; // Formatting codes - const short reset = 0; + const short reset = FOREGROUND_INTENSITY; const short bold = FOREGROUND_INTENSITY; const short dark = reset; // Not implemented in windows const short underline = reset; // Not implemented in windows @@ -45,6 +45,7 @@ public: const short concealed = reset; // Not implemented in windows // Foreground colors + const short black = 0; const short grey = bold; const short red = FOREGROUND_RED; const short green = FOREGROUND_GREEN; @@ -65,20 +66,23 @@ public: const short on_white = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; void set_color( level::level_enum level, const short& color ); - sink_ptr& wrapped_sink(); protected: virtual void _sink_it(const details::log_msg& msg) override; - sink_ptr sink_; + void SetConsoleColor( WORD* Attributes, DWORD Color ); + void ResetConsoleColor( WORD Attributes ); + std::map colors_; + std::ostream& _ostream; + bool _force_flush; }; typedef wincolor_sink wincolor_sink_st; typedef wincolor_sink wincolor_sink_mt; template -inline wincolor_sink::wincolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) +inline wincolor_sink::wincolor_sink(std::ostream& os, bool force_flush=false) :_ostream(os), _force_flush(force_flush) { colors_[level::trace] = cyan; colors_[level::debug] = cyan; @@ -97,17 +101,18 @@ template inline void wincolor_sink::_sink_it( const details::log_msg& msg ) { // Wrap the originally formatted message in color codes - SetConsoleTextAttribute(GetStdHandle( STD_OUTPUT_HANDLE ), colors_[msg.level]); - SetConsoleTextAttribute(GetStdHandle( STD_ERROR_HANDLE ), colors_[msg.level]); - sink_->log( msg ); - SetConsoleTextAttribute(GetStdHandle( STD_ERROR_HANDLE ), reset); - SetConsoleTextAttribute(GetStdHandle( STD_OUTPUT_HANDLE ), reset); + WORD Attributes = 0; + SetConsoleColor(&Attributes, colors_[msg.level]); + _ostream.write( msg.formatted.data(), msg.formatted.size() ); + if (_force_flush) + _ostream.flush(); + ResetConsoleColor(Attributes); } template inline void wincolor_sink::flush() { - sink_->flush(); + _ostream.flush(); } template @@ -117,17 +122,30 @@ inline void wincolor_sink::set_color( level::level_enum level, const shor } template -inline sink_ptr& wincolor_sink::wrapped_sink() +inline wincolor_sink::~wincolor_sink() { - return sink_; + flush(); } template -inline wincolor_sink::~wincolor_sink() +void wincolor_sink::SetConsoleColor( WORD* Attributes, DWORD Color ) { - flush(); + CONSOLE_SCREEN_BUFFER_INFO Info; + HANDLE hStdout = GetStdHandle( STD_OUTPUT_HANDLE ); + GetConsoleScreenBufferInfo( hStdout, &Info ); + *Attributes = Info.wAttributes; + SetConsoleTextAttribute( hStdout, Color ); + SetConsoleTextAttribute( GetStdHandle(STD_ERROR_HANDLE), Color ); } +template +void wincolor_sink::ResetConsoleColor( WORD Attributes ) +{ + SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), Attributes ); + SetConsoleTextAttribute( GetStdHandle( STD_ERROR_HANDLE ), Attributes ); +} + + } // namespace sinks } // namespace spdlog