From 0cfdad4d0b6dde761debe408fc7c9501e697b914 Mon Sep 17 00:00:00 2001 From: gabime Date: Wed, 12 Oct 2016 15:10:10 +0300 Subject: [PATCH] Windows console color support. Replaced color param in API with new functions --- README.md | 156 ++++++++++++++------------- example/example.cpp | 28 ++--- example/example.vcxproj | 1 + include/spdlog/details/spdlog_impl.h | 134 ++++++++++++++++------- include/spdlog/sinks/stdout_sinks.h | 100 ++++++++--------- include/spdlog/sinks/wincolor_sink.h | 116 ++++++++++++++++++++ include/spdlog/spdlog.h | 15 ++- 7 files changed, 370 insertions(+), 180 deletions(-) create mode 100644 include/spdlog/sinks/wincolor_sink.h diff --git a/README.md b/README.md index e023c56b..784373c8 100644 --- a/README.md +++ b/README.md @@ -70,81 +70,87 @@ void user_defined_example(); void err_handler_example(); namespace spd = spdlog; -int main(int, char*[]) -{ - try - { - // Multithreaded color console - auto console = spd::stdout_logger_mt("console", true); - console->info("Welcome to spdlog!"); - console->info("An info message example {}..", 1); - - // Formatting examples - console->warn("Easy padding in numbers like {:08d}", 12); - console->critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); - console->info("Support for floats {:03.2f}", 1.23456); - console->info("Positional args are {1} {0}..", "too", "supported"); - - console->info("{:<30}", "left aligned"); - console->info("{:>30}", "right aligned"); - console->info("{:^30}", "centered"); - - spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"); - - // Runtime log levels - spd::set_level(spd::level::info); //Set global log level to info - console->debug("This message shold not be displayed!"); - console->set_level(spd::level::debug); // Set specific logger's log level - console->debug("This message shold be displayed.."); - - // Create basic file logger (not rotated) - auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic.txt"); - my_logger->info("Some log message"); - - - // Create a file rotating logger with 5mb size max and 3 rotated files - auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/mylogfile", 1048576 * 5, 3); - for (int i = 0; i < 10; ++i) - rotating_logger->info("{} * {} equals {:>10}", i, i, i*i); - - // Create a daily logger - a new file is created every day on 2:30am - auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily", 2, 30); - daily_logger->info(123.44); - - // Customize msg format for all messages - spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***"); - rotating_logger->info("This is another message with custom format"); - - // Compile time debug or trace macros. - // Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef SPDLOG_TRACE_ON - SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23); - SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23); - - // Asynchronous logging is very fast.. - // Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous.. - async_example(); - - // syslog example. linux/osx only.. - syslog_example(); - - // Log user-defined types example.. - user_defined_example(); - - // Change default log error handler - err_handler_example(); - - // Apply a function on all registered loggers - spd::apply_all([&](std::shared_ptr l) {l->info("End of example."); }); - - // Release and close all loggers - spdlog::drop_all(); - } - // Exceptions will only be thrown upon failed logger or sink construction (not during logging) - catch (const spd::spdlog_ex& ex) - { - std::cout << "Log init failed: " << ex.what() << std::endl; - return 1; - } +int main(int, char*[]) +{ + try + { + // Console logger with color + auto console = spd::stdout_color_mt("console"); + console->info("Welcome to spdlog!"); + console->error("Some error message with arg{}..", 1); + + // Formatting examples + console->warn("Easy padding in numbers like {:08d}", 12); + console->critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); + console->info("Support for floats {:03.2f}", 1.23456); + console->info("Positional args are {1} {0}..", "too", "supported"); + console->info("{:<30}", "left aligned"); + + + spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"); + + // Create basic file logger (not rotated) + auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic.txt"); + my_logger->info("Some log message"); + + // Create a file rotating logger with 5mb size max and 3 rotated files + auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/mylogfile", 1048576 * 5, 3); + for (int i = 0; i < 10; ++i) + rotating_logger->info("{} * {} equals {:>10}", i, i, i*i); + + // Create a daily logger - a new file is created every day on 2:30am + auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily", 2, 30); + // trigger flush if the log severity is error or higher + daily_logger->flush_on(spd::level::err); + daily_logger->info(123.44); + + // Customize msg format for all messages + spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***"); + rotating_logger->info("This is another message with custom format"); + + + // Runtime log levels + spd::set_level(spd::level::info); //Set global log level to info + console->debug("This message shold not be displayed!"); + console->set_level(spd::level::debug); // Set specific logger's log level + console->debug("This message shold be displayed.."); + + // Compile time log levels + // define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON + SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23); + SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23); + + // Asynchronous logging is very fast.. + // Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous.. + async_example(); + + // syslog example. linux/osx only + syslog_example(); + + // android example. compile with NDK + android_example(); + + // Log user-defined types example + user_defined_example(); + + // Change default log error handler + err_handler_example(); + + // Apply a function on all registered loggers + spd::apply_all([&](std::shared_ptr l) + { + l->info("End of example."); + }); + + // Release and close all loggers + spdlog::drop_all(); + } + // Exceptions will only be thrown upon failed logger or sink construction (not during logging) + catch (const spd::spdlog_ex& ex) + { + std::cout << "Log init failed: " << ex.what() << std::endl; + return 1; + } } void async_example() diff --git a/example/example.cpp b/example/example.cpp index 2323b57d..678dd7b6 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -22,29 +22,22 @@ int main(int, char*[]) { try { - // Multithreaded color console - auto console = spd::stdout_logger_mt("console", true); + // Console logger with color + auto console = spd::stdout_color_mt("console"); console->info("Welcome to spdlog!"); - console->error("An error message example {}..", 1); + console->error("Some error message with arg{}..", 1); // Formatting examples console->warn("Easy padding in numbers like {:08d}", 12); console->critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); console->info("Support for floats {:03.2f}", 1.23456); console->info("Positional args are {1} {0}..", "too", "supported"); - console->info("{:<30}", "left aligned"); - console->info("{:>30}", "right aligned"); - console->info("{:^30}", "centered"); + spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"); - // Runtime log levels - spd::set_level(spd::level::info); //Set global log level to info - console->debug("This message shold not be displayed!"); - console->set_level(spd::level::debug); // Set specific logger's log level - console->debug("This message shold be displayed.."); - + // Create basic file logger (not rotated) auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic.txt"); my_logger->info("Some log message"); @@ -64,8 +57,15 @@ int main(int, char*[]) spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***"); rotating_logger->info("This is another message with custom format"); - // Compile time debug or trace macros. - // Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef SPDLOG_TRACE_ON + + // Runtime log levels + spd::set_level(spd::level::info); //Set global log level to info + console->debug("This message shold not be displayed!"); + console->set_level(spd::level::debug); // Set specific logger's log level + console->debug("This message shold be displayed.."); + + // Compile time log levels + // define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23); SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23); diff --git a/example/example.vcxproj b/example/example.vcxproj index e0c58aee..2b8c4e55 100644 --- a/example/example.vcxproj +++ b/example/example.vcxproj @@ -42,6 +42,7 @@ + diff --git a/include/spdlog/details/spdlog_impl.h b/include/spdlog/details/spdlog_impl.h index 820e03a4..e1bbee2f 100644 --- a/include/spdlog/details/spdlog_impl.h +++ b/include/spdlog/details/spdlog_impl.h @@ -15,7 +15,13 @@ #ifdef SPDLOG_ENABLE_SYSLOG #include #endif + +#ifdef _WIN32 +#include +#else #include +#endif + #ifdef __ANDROID__ #include @@ -28,160 +34,212 @@ inline void spdlog::register_logger(std::shared_ptr logger) { - return details::registry::instance().register_logger(logger); + return details::registry::instance().register_logger(logger); } inline std::shared_ptr spdlog::get(const std::string& name) { - return details::registry::instance().get(name); + return details::registry::instance().get(name); } inline void spdlog::drop(const std::string &name) { - details::registry::instance().drop(name); + details::registry::instance().drop(name); } // Create multi/single threaded simple file logger inline std::shared_ptr spdlog::basic_logger_mt(const std::string& logger_name, const filename_t& filename, bool truncate) { - return create(logger_name, filename, truncate); + return create(logger_name, filename, truncate); } inline std::shared_ptr spdlog::basic_logger_st(const std::string& logger_name, const filename_t& filename, bool truncate) { - return create(logger_name, filename, truncate); + return create(logger_name, filename, truncate); } // 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) { - return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), max_file_size, max_files); + return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), max_file_size, max_files); } 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) { - return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), max_file_size, max_files); + return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), max_file_size, max_files); } // 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) { - return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), hour, minute); + return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), hour, minute); } inline std::shared_ptr spdlog::daily_logger_st(const std::string& logger_name, const filename_t& filename, int hour, int minute) { - return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), hour, minute); + return create(logger_name, filename, SPDLOG_FILENAME_T("txt"), hour, minute); } -// 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); + +// +// stdout/stderr loggers +// +inline std::shared_ptr spdlog::stdout_logger_mt(const std::string& logger_name) +{ + return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_mt::instance()); } -inline std::shared_ptr spdlog::stdout_logger_mt(const std::string& logger_name, bool color) +inline std::shared_ptr spdlog::stdout_logger_st(const std::string& logger_name) { - return create_console_logger(logger_name, sinks::stdout_sink_mt::instance(), color); + return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_st::instance()); } -inline std::shared_ptr spdlog::stdout_logger_st(const std::string& logger_name, bool color) +inline std::shared_ptr spdlog::stderr_logger_mt(const std::string& logger_name) { - return create_console_logger(logger_name, sinks::stdout_sink_st::instance(), color); + return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_mt::instance()); } -inline std::shared_ptr spdlog::stderr_logger_mt(const std::string& logger_name, bool color) +inline std::shared_ptr spdlog::stderr_logger_st(const std::string& logger_name) { - return create_console_logger(logger_name, sinks::stderr_sink_mt::instance(), color); + return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_st::instance()); } -inline std::shared_ptr spdlog::stderr_logger_st(const std::string& logger_name, bool color) +// +// stdout/stderr color loggers +// +#ifdef _WIN32 +inline std::shared_ptr spdlog::stdout_color_mt(const std::string& logger_name) { - return create_console_logger(logger_name, sinks::stderr_sink_st::instance(), color); + auto sink = std::make_shared(); + return spdlog::details::registry::instance().create(logger_name, sink); } +inline std::shared_ptr spdlog::stdout_color_st(const std::string& logger_name) +{ + auto sink = std::make_shared(); + return spdlog::details::registry::instance().create(logger_name, sink); +} + +inline std::shared_ptr spdlog::stderr_color_mt(const std::string& logger_name) +{ + auto sink = std::make_shared(); + return spdlog::details::registry::instance().create(logger_name, sink); +} + + +inline std::shared_ptr spdlog::stderr_color_st(const std::string& logger_name) +{ + auto sink = std::make_shared(); + return spdlog::details::registry::instance().create(logger_name, sink); +} + +#else //ansi terminal colors + +inline std::shared_ptr spdlog::stdout_color_mt(const std::string& logger_name) +{ + auto sink = std::make_shared(spdlog::sinks::stdout_sink_mt::instance()); + return spdlog::details::registry::instance().create(logger_name, sink); +} + +inline std::shared_ptr spdlog::stdout_color_st(const std::string& logger_name) +{ + auto sink = std::make_shared(spdlog::sinks::stdout_sink_st::instance()); + return spdlog::details::registry::instance().create(logger_name, sink); +} + +inline std::shared_ptr spdlog::stderr_color_mt(const std::string& logger_name) +{ + auto sink = std::make_shared(spdlog::sinks::stderr_sink_mt::instance()); + return spdlog::details::registry::instance().create(logger_name, sink); +} + +inline std::shared_ptr spdlog::stderr_color_st(const std::string& logger_name) +{ + auto sink = std::make_shared(spdlog::sinks::stderr_sink_st::instance()); + return spdlog::details::registry::instance().create(logger_name, sink); +} +#endif + #ifdef SPDLOG_ENABLE_SYSLOG // 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); + return create(logger_name, syslog_ident, syslog_option); } #endif #ifdef __ANDROID__ inline std::shared_ptr spdlog::android_logger(const std::string& logger_name, const std::string& tag) { - return create(logger_name, tag); + return create(logger_name, tag); } #endif // Create and register a logger a single sink inline std::shared_ptr spdlog::create(const std::string& logger_name, const spdlog::sink_ptr& sink) { - return details::registry::instance().create(logger_name, sink); + return details::registry::instance().create(logger_name, sink); } //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); + 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 }); + 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); + 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); + details::registry::instance().formatter(f); } inline void spdlog::set_pattern(const std::string& format_string) { - return details::registry::instance().set_pattern(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); + return details::registry::instance().set_level(log_level); } inline void spdlog::set_error_handler(log_err_handler handler) { - return details::registry::instance().set_error_handler(handler); + return details::registry::instance().set_error_handler(handler); } 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, const std::function& worker_teardown_cb) { - details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb); + details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb); } inline void spdlog::set_sync_mode() { - details::registry::instance().set_sync_mode(); + details::registry::instance().set_sync_mode(); } inline void spdlog::apply_all(std::function)> fun) { - details::registry::instance().apply_all(fun); + details::registry::instance().apply_all(fun); } inline void spdlog::drop_all() { - details::registry::instance().drop_all(); + details::registry::instance().drop_all(); } diff --git a/include/spdlog/sinks/stdout_sinks.h b/include/spdlog/sinks/stdout_sinks.h index 30c19a54..f1f5c812 100644 --- a/include/spdlog/sinks/stdout_sinks.h +++ b/include/spdlog/sinks/stdout_sinks.h @@ -14,62 +14,64 @@ namespace spdlog { -namespace sinks -{ + namespace sinks + { -template -class stdout_sink : public base_sink -{ - using MyType = stdout_sink; -public: - stdout_sink() {} - static std::shared_ptr instance() - { - static std::shared_ptr instance = std::make_shared(); - return instance; - } + template + class stdout_sink: public base_sink + { + using MyType = stdout_sink; + public: + stdout_sink() + {} + static std::shared_ptr instance() + { + static std::shared_ptr instance = std::make_shared(); + return instance; + } - void _sink_it(const details::log_msg& msg) override - { - fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), stdout); - flush(); - } + void _sink_it(const details::log_msg& msg) override + { + fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), stdout); + flush(); + } - void flush() override - { - fflush(stdout); - } -}; + void flush() override + { + fflush(stdout); + } + }; -typedef stdout_sink stdout_sink_st; -typedef stdout_sink stdout_sink_mt; + typedef stdout_sink stdout_sink_st; + typedef stdout_sink stdout_sink_mt; -template -class stderr_sink : public base_sink -{ - using MyType = stderr_sink; -public: - stderr_sink() {} - static std::shared_ptr instance() - { - static std::shared_ptr instance = std::make_shared(); - return instance; - } + template + class stderr_sink: public base_sink + { + using MyType = stderr_sink; + public: + stderr_sink() + {} + static std::shared_ptr instance() + { + static std::shared_ptr instance = std::make_shared(); + return instance; + } - void _sink_it(const details::log_msg& msg) override - { - fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), stderr); - flush(); - } + void _sink_it(const details::log_msg& msg) override + { + fwrite(msg.formatted.data(), sizeof(char), msg.formatted.size(), stderr); + flush(); + } - void flush() override - { - fflush(stderr); - } -}; + void flush() override + { + fflush(stderr); + } + }; -typedef stderr_sink stderr_sink_mt; -typedef stderr_sink stderr_sink_st; -} + typedef stderr_sink stderr_sink_mt; + typedef stderr_sink stderr_sink_st; + } } diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h new file mode 100644 index 00000000..a299c763 --- /dev/null +++ b/include/spdlog/sinks/wincolor_sink.h @@ -0,0 +1,116 @@ +// +// Copyright(c) 2016 spdlog +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +namespace spdlog +{ + namespace sinks + { + /* + * Windows color console sink. Uses WriteConsoleA to write to the console with colors + */ + template + class wincolor_sink: public base_sink + { + public: + const WORD BOLD = FOREGROUND_INTENSITY; + const WORD RED = FOREGROUND_RED; + const WORD CYAN = FOREGROUND_GREEN | FOREGROUND_BLUE; + const WORD WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + const WORD YELLOW = FOREGROUND_RED | FOREGROUND_GREEN; + + wincolor_sink(HANDLE std_handle): out_handle_(std_handle) + { + colors_[level::trace] = CYAN; + colors_[level::debug] = CYAN; + colors_[level::info] = WHITE | BOLD; + colors_[level::warn] = YELLOW | BOLD; + colors_[level::err] = RED | BOLD; // red bold + colors_[level::critical] = BACKGROUND_RED | WHITE | BOLD; // white bold on red background + colors_[level::off] = 0; + } + + virtual ~wincolor_sink() + { + flush(); + } + + wincolor_sink(const wincolor_sink& other) = delete; + wincolor_sink& operator=(const wincolor_sink& other) = delete; + + virtual void _sink_it(const details::log_msg& msg) override + { + auto color = colors_[msg.level]; + auto orig_attribs = set_console_attribs(color); + WriteConsoleA(out_handle_, msg.formatted.data(), msg.formatted.size(), nullptr, nullptr); + SetConsoleTextAttribute(out_handle_, orig_attribs); //reset to orig colors + } + + virtual void flush() override + { + // windows console always flushed? + } + + // change the color for the given level + void set_color(level::level_enum level, WORD color) + { + std::lock_guard lock(_mutex); + colors_[level] = color; + } + + private: + HANDLE out_handle_; + std::map colors_; + + // set color and return the orig console attributes (for resetting later) + WORD set_console_attribs(WORD attribs) + { + CONSOLE_SCREEN_BUFFER_INFO orig_buffer_info; + GetConsoleScreenBufferInfo(out_handle_, &orig_buffer_info); + SetConsoleTextAttribute(out_handle_, attribs); + return orig_buffer_info.wAttributes; //return orig attribs + } + }; + + // + // windows color console to stdout + // + template + class wincolor_stdout_sink: public wincolor_sink + { + public: + wincolor_stdout_sink():wincolor_sink(GetStdHandle(STD_OUTPUT_HANDLE)) + {} + }; + + typedef wincolor_stdout_sink wincolor_stdout_sink_mt; + typedef wincolor_stdout_sink wincolor_stdout_sink_st; + + // + // windows color console to stderr + // + template + class wincolor_stderr_sink: public wincolor_sink + { + public: + wincolor_stderr_sink():wincolor_sink(GetStdHandle(STD_ERROR_HANDLE)) + {} + }; + + typedef wincolor_stderr_sink wincolor_stderr_sink_mt; + typedef wincolor_stderr_sink wincolor_stderr_sink_st; + + } +} \ No newline at end of file diff --git a/include/spdlog/spdlog.h b/include/spdlog/spdlog.h index d4f4203e..b4bfc84e 100644 --- a/include/spdlog/spdlog.h +++ b/include/spdlog/spdlog.h @@ -88,10 +88,17 @@ std::shared_ptr daily_logger_st(const std::string& logger_name, const fi // // Create and register stdout/stderr loggers // -std::shared_ptr stdout_logger_mt(const std::string& logger_name, bool color = false); -std::shared_ptr stdout_logger_st(const std::string& logger_name, bool color = false); -std::shared_ptr stderr_logger_mt(const std::string& logger_name, bool color = false); -std::shared_ptr stderr_logger_st(const std::string& logger_name, bool color = false); +std::shared_ptr stdout_logger_mt(const std::string& logger_name); +std::shared_ptr stdout_logger_st(const std::string& logger_name); +std::shared_ptr stderr_logger_mt(const std::string& logger_name); +std::shared_ptr stderr_logger_st(const std::string& logger_name); +// +// Create and register colored stdout/stderr loggers +// +std::shared_ptr stdout_color_mt(const std::string& logger_name); +std::shared_ptr stdout_color_st(const std::string& logger_name); +std::shared_ptr stderr_color_mt(const std::string& logger_name); +std::shared_ptr stderr_color_st(const std::string& logger_name); //