From f1e3f676e3b090def505234b44ed304b6d5b9a6c Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Wed, 13 Apr 2016 01:12:22 -0400 Subject: [PATCH 01/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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 From 5d5e0726d9fcc3e169b480ef17bd7c4fee9191c9 Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 11:20:18 -0400 Subject: [PATCH 11/18] Undo changes for windows colors --- include/spdlog/sinks/ansicolor_sink.h | 229 +++++++++++++------------- 1 file changed, 114 insertions(+), 115 deletions(-) diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index 664b2599..6f2a690b 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -1,115 +1,114 @@ -// -// Copyright(c) 2016 Kevin M. Godby (a modified version by spdlog). -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -#include -#include - -#include -#include - -namespace spdlog -{ -namespace sinks -{ - -/** - * @brief The ansi_color_sink is a decorator around another sink and prefixes - * the output with an ANSI escape sequence color code depending on the severity - * of the message. - */ -class ansicolor_sink : public sink -{ -public: - ansicolor_sink(sink_ptr wrapped_sink); - virtual ~ansicolor_sink(); - - ansicolor_sink(const ansicolor_sink& other) = delete; - ansicolor_sink& operator=(const ansicolor_sink& other) = delete; - - virtual void log(const details::log_msg& msg) override; - virtual void flush() override; - - void set_color(level::level_enum level, const std::string& color); - - /// Formatting codes - const std::string reset = "\033[00m"; - const std::string bold = "\033[1m"; - const std::string dark = "\033[2m"; - const std::string underline = "\033[4m"; - const std::string blink = "\033[5m"; - const std::string reverse = "\033[7m"; - const std::string concealed = "\033[8m"; - - // Foreground colors - const std::string grey = "\033[30m"; - const std::string red = "\033[31m"; - const std::string green = "\033[32m"; - const std::string yellow = "\033[33m"; - const std::string blue = "\033[34m"; - const std::string magenta = "\033[35m"; - const std::string cyan = "\033[36m"; - const std::string white = "\033[37m"; - - /// Background colors - const std::string on_grey = "\033[40m"; - const std::string on_red = "\033[41m"; - const std::string on_green = "\033[42m"; - const std::string on_yellow = "\033[43m"; - const std::string on_blue = "\033[44m"; - const std::string on_magenta = "\033[45m"; - const std::string on_cyan = "\033[46m"; - const std::string on_white = "\033[47m"; - - -protected: - sink_ptr sink_; - std::map colors_; -}; - -inline ansicolor_sink::ansicolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) -{ - 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; -} - -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; - m.formatted << prefix << s << suffix; - sink_->log(m); -} - -inline void ansicolor_sink::flush() -{ - sink_->flush(); -} - -inline void ansicolor_sink::set_color(level::level_enum level, const std::string& color) -{ - colors_[level] = color; -} - -inline ansicolor_sink::~ansicolor_sink() -{ - flush(); -} - -} // namespace sinks -} // namespace spdlog - +// +// Copyright(c) 2016 Kevin M. Godby (a modified version by spdlog). +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +#pragma once + +#include +#include + +#include +#include + +namespace spdlog +{ +namespace sinks +{ + +/** + * @brief The ansi_color_sink is a decorator around another sink and prefixes + * the output with an ANSI escape sequence color code depending on the severity + * of the message. + */ +class ansicolor_sink : public sink +{ +public: + ansicolor_sink(sink_ptr wrapped_sink); + virtual ~ansicolor_sink(); + + ansicolor_sink(const ansicolor_sink& other) = delete; + ansicolor_sink& operator=(const ansicolor_sink& other) = delete; + + virtual void log(const details::log_msg& msg) override; + virtual void flush() override; + + void set_color(level::level_enum level, const std::string& color); + + /// Formatting codes + const std::string reset = "\033[00m"; + const std::string bold = "\033[1m"; + const std::string dark = "\033[2m"; + const std::string underline = "\033[4m"; + const std::string blink = "\033[5m"; + const std::string reverse = "\033[7m"; + const std::string concealed = "\033[8m"; + + // Foreground colors + const std::string grey = "\033[30m"; + const std::string red = "\033[31m"; + const std::string green = "\033[32m"; + const std::string yellow = "\033[33m"; + const std::string blue = "\033[34m"; + const std::string magenta = "\033[35m"; + const std::string cyan = "\033[36m"; + const std::string white = "\033[37m"; + + /// Background colors + const std::string on_grey = "\033[40m"; + const std::string on_red = "\033[41m"; + const std::string on_green = "\033[42m"; + const std::string on_yellow = "\033[43m"; + const std::string on_blue = "\033[44m"; + const std::string on_magenta = "\033[45m"; + const std::string on_cyan = "\033[46m"; + const std::string on_white = "\033[47m"; + +protected: + sink_ptr sink_; + std::map colors_; +}; + +inline ansicolor_sink::ansicolor_sink(sink_ptr wrapped_sink) : sink_(wrapped_sink) +{ + 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; +} + +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; + m.formatted << prefix << s << suffix; + sink_->log(m); +} + +inline void ansicolor_sink::flush() +{ + sink_->flush(); +} + +inline void ansicolor_sink::set_color(level::level_enum level, const std::string& color) +{ + colors_[level] = color; +} + +inline ansicolor_sink::~ansicolor_sink() +{ + flush(); +} + +} // namespace sinks +} // namespace spdlog + From b5d2307157701d183eec04e8456b33adbc97b02e Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 11:21:32 -0400 Subject: [PATCH 12/18] 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 37edf7f4f8ea4db2d3a8d6e36912f94439b8d964 Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 12:03:34 -0400 Subject: [PATCH 13/18] 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 e76cf117c2f54e30317d6d0fafb0566bd0ef17ba Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 12:08:38 -0400 Subject: [PATCH 14/18] 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 5f52c114e5889e1144a3e9702d344d4ce23cc9b9 Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 12:20:36 -0400 Subject: [PATCH 15/18] create_console_logger now uses the correct color sink depending on your platform --- include/spdlog/details/spdlog_impl.h | 303 ++++++++++++++------------- 1 file changed, 154 insertions(+), 149 deletions(-) diff --git a/include/spdlog/details/spdlog_impl.h b/include/spdlog/details/spdlog_impl.h index 3942e5a7..423ec43d 100644 --- a/include/spdlog/details/spdlog_impl.h +++ b/include/spdlog/details/spdlog_impl.h @@ -1,149 +1,154 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -// -// Global registry functions -// -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -inline void spdlog::register_logger(std::shared_ptr logger) -{ - return details::registry::instance().register_logger(logger); -} - -inline std::shared_ptr spdlog::get(const std::string& name) -{ - return details::registry::instance().get(name); -} - -inline void spdlog::drop(const std::string &name) -{ - details::registry::instance().drop(name); -} - -// Create multi/single threaded rotating file logger -inline std::shared_ptr spdlog::rotating_logger_mt(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files, bool force_flush) -{ - return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), max_file_size, max_files, force_flush); -} - -inline std::shared_ptr spdlog::rotating_logger_st(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files, bool force_flush) -{ - return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), max_file_size, max_files, force_flush); -} - -// Create file logger which creates new file at midnight): -inline std::shared_ptr spdlog::daily_logger_mt(const std::string& logger_name, const filename_t& filename, int hour, int minute, bool force_flush) -{ - return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), hour, minute, force_flush); -} - -inline std::shared_ptr spdlog::daily_logger_st(const std::string& logger_name, const filename_t& filename, int hour, int minute, bool force_flush) -{ - return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), hour, minute, force_flush); -} - -// 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) -{ - if (color) //use color wrapper sink - sink = std::make_shared(sink); - return spdlog::details::registry::instance().create(logger_name, sink); -} - -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); -} - -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); -} - -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); -} - -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); -} - -#if defined(__linux__) || defined(__APPLE__) -// Create syslog logger -inline std::shared_ptr spdlog::syslog_logger(const std::string& logger_name, const std::string& syslog_ident, int syslog_option) -{ - return create(logger_name, syslog_ident, syslog_option); -} -#endif - - -//Create logger with multiple sinks - -inline std::shared_ptr spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks) -{ - return details::registry::instance().create(logger_name, sinks); -} - - -template -inline std::shared_ptr spdlog::create(const std::string& logger_name, Args... args) -{ - sink_ptr sink = std::make_shared(args...); - return details::registry::instance().create(logger_name, { sink }); -} - - -template -inline std::shared_ptr spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) -{ - return details::registry::instance().create(logger_name, sinks_begin, sinks_end); -} - -inline void spdlog::set_formatter(spdlog::formatter_ptr f) -{ - details::registry::instance().formatter(f); -} - -inline void spdlog::set_pattern(const std::string& format_string) -{ - return details::registry::instance().set_pattern(format_string); -} - -inline void spdlog::set_level(level::level_enum log_level) -{ - return details::registry::instance().set_level(log_level); -} - - -inline void spdlog::set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms) -{ - details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms); -} - -inline void spdlog::set_sync_mode() -{ - details::registry::instance().set_sync_mode(); -} - -inline void spdlog::drop_all() -{ - details::registry::instance().drop_all(); -} - +// +// Copyright(c) 2015 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +#pragma once + +// +// Global registry functions +// +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +inline void spdlog::register_logger(std::shared_ptr logger) +{ + return details::registry::instance().register_logger(logger); +} + +inline std::shared_ptr spdlog::get(const std::string& name) +{ + return details::registry::instance().get(name); +} + +inline void spdlog::drop(const std::string &name) +{ + details::registry::instance().drop(name); +} + +// Create multi/single threaded rotating file logger +inline std::shared_ptr spdlog::rotating_logger_mt(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files, bool force_flush) +{ + return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), max_file_size, max_files, force_flush); +} + +inline std::shared_ptr spdlog::rotating_logger_st(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files, bool force_flush) +{ + return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), max_file_size, max_files, force_flush); +} + +// Create file logger which creates new file at midnight): +inline std::shared_ptr spdlog::daily_logger_mt(const std::string& logger_name, const filename_t& filename, int hour, int minute, bool force_flush) +{ + return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), hour, minute, force_flush); +} + +inline std::shared_ptr spdlog::daily_logger_st(const std::string& logger_name, const filename_t& filename, int hour, int minute, bool force_flush) +{ + return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), hour, minute, force_flush); +} + +// 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) +{ + 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 spdlog::stdout_logger_mt(const std::string& logger_name, bool color) +{ + return create_console_logger(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); +} + +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); +} + +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); +} + +#if defined(__linux__) || defined(__APPLE__) +// Create syslog logger +inline std::shared_ptr spdlog::syslog_logger(const std::string& logger_name, const std::string& syslog_ident, int syslog_option) +{ + return create(logger_name, syslog_ident, syslog_option); +} +#endif + + +//Create logger with multiple sinks + +inline std::shared_ptr spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks) +{ + return details::registry::instance().create(logger_name, sinks); +} + + +template +inline std::shared_ptr spdlog::create(const std::string& logger_name, Args... args) +{ + sink_ptr sink = std::make_shared(args...); + return details::registry::instance().create(logger_name, { sink }); +} + + +template +inline std::shared_ptr spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) +{ + return details::registry::instance().create(logger_name, sinks_begin, sinks_end); +} + +inline void spdlog::set_formatter(spdlog::formatter_ptr f) +{ + details::registry::instance().formatter(f); +} + +inline void spdlog::set_pattern(const std::string& format_string) +{ + return details::registry::instance().set_pattern(format_string); +} + +inline void spdlog::set_level(level::level_enum log_level) +{ + return details::registry::instance().set_level(log_level); +} + + +inline void spdlog::set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms) +{ + details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms); +} + +inline void spdlog::set_sync_mode() +{ + details::registry::instance().set_sync_mode(); +} + +inline void spdlog::drop_all() +{ + details::registry::instance().drop_all(); +} + From 93f0093b2a8cb5f4498552a961f8163fc28129ca Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 16:19:04 -0400 Subject: [PATCH 16/18] 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 b8872b7b8e6581217128d52c9bac5bca968e0b2d Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Thu, 14 Apr 2016 18:06:51 -0400 Subject: [PATCH 17/18] 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 8e3572aa188988f7b7025583ae48a9f998879802 Mon Sep 17 00:00:00 2001 From: Christopher Torres Date: Sun, 24 Apr 2016 22:40:25 -0400 Subject: [PATCH 18/18] 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