diff --git a/include/spdlog/details/spdlog_impl.h b/include/spdlog/details/spdlog_impl.h index 3942e5a7..1414c8a8 100644 --- a/include/spdlog/details/spdlog_impl.h +++ b/include/spdlog/details/spdlog_impl.h @@ -1,149 +1,156 @@ -// -// 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 + +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_st(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 create_console_logger_mt(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_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_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_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_st(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(); +} + 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 + diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h new file mode 100644 index 00000000..5bc744d9 --- /dev/null +++ b/include/spdlog/sinks/wincolor_sink.h @@ -0,0 +1,151 @@ +// +// 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 +{ + +/** + * @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. + */ +template +class wincolor_sink : public base_sink +{ +public: + wincolor_sink(std::ostream& os, bool force_flush=false); + virtual ~wincolor_sink(); + + wincolor_sink(const wincolor_sink& other) = delete; + wincolor_sink& operator=(const wincolor_sink& other) = delete; + + virtual void flush() override; + + // Formatting codes + 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 + 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 black = 0; + 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 ); + +protected: + virtual void _sink_it(const details::log_msg& msg) override; + + 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(std::ostream& os, bool force_flush=false) :_ostream(os), _force_flush(force_flush) +{ + 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; +} + +template +inline void wincolor_sink::_sink_it( const details::log_msg& msg ) +{ + // Wrap the originally formatted message in color codes + 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() +{ + _ostream.flush(); +} + +template +inline void wincolor_sink::set_color( level::level_enum level, const short& color ) +{ + colors_[level] = color; +} + +template +inline wincolor_sink::~wincolor_sink() +{ + flush(); +} + +template +void wincolor_sink::SetConsoleColor( WORD* Attributes, DWORD Color ) +{ + 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 +