From 2b5c3615fde7494bd030de0e6eb4d8c4de2075a1 Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Tue, 28 Mar 2017 03:25:53 +0300 Subject: [PATCH 01/33] Update async_log_helper.h --- include/spdlog/details/async_log_helper.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/spdlog/details/async_log_helper.h b/include/spdlog/details/async_log_helper.h index 92a0f4cd..f253d364 100644 --- a/include/spdlog/details/async_log_helper.h +++ b/include/spdlog/details/async_log_helper.h @@ -9,8 +9,6 @@ // If the internal queue of log messages reaches its max size, // then the client call will block until there is more room. // -// If the back thread throws during logging, a spdlog::spdlog_ex exception -// will be thrown in client's thread when tries to log the next message #pragma once From b638c71d262e296e8a7dd490fa2311006475495a Mon Sep 17 00:00:00 2001 From: Oleksii Mandrychenko Date: Wed, 29 Mar 2017 11:27:59 +0100 Subject: [PATCH 02/33] [#404] Reading past valid address with multisink logger - Initialising atomic value See examples at http://stackoverflow.com/q/36320008/706456 This issue was discovered with dr memory tool on Windows platform, Visual Studio 2015 C++ 11 --- include/spdlog/logger.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index 58b4841a..aec1d203 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -87,7 +87,7 @@ protected: spdlog::level_t _level; spdlog::level_t _flush_level; log_err_handler _err_handler; - std::atomic _last_err_time; + std::atomic _last_err_time {0}; // init atomic value to avoid reads of uninitialised memory }; } From 6a41bc40af0d6f060e7b47838bd8126081f1e155 Mon Sep 17 00:00:00 2001 From: Oleksii Mandrychenko Date: Wed, 29 Mar 2017 13:53:11 +0100 Subject: [PATCH 03/33] [#404] Reading past valid address with multisink logger - Initialising atomic value See examples at http://stackoverflow.com/q/36320008/706456 This issue was discovered with dr memory tool on Windows platform, Visual Studio 2015 C++ 11 --- include/spdlog/details/mpmc_bounded_q.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/spdlog/details/mpmc_bounded_q.h b/include/spdlog/details/mpmc_bounded_q.h index 3a46e8eb..c963bc93 100644 --- a/include/spdlog/details/mpmc_bounded_q.h +++ b/include/spdlog/details/mpmc_bounded_q.h @@ -159,9 +159,9 @@ private: cell_t* const buffer_; size_t const buffer_mask_; cacheline_pad_t pad1_; - std::atomic enqueue_pos_; + std::atomic enqueue_pos_ {0}; cacheline_pad_t pad2_; - std::atomic dequeue_pos_; + std::atomic dequeue_pos_ {0}; cacheline_pad_t pad3_; mpmc_bounded_queue(mpmc_bounded_queue const&) = delete; From b5d838cc32a7fe4eec0b4c94ce7c0f48d064a733 Mon Sep 17 00:00:00 2001 From: Oleksii Mandrychenko Date: Wed, 29 Mar 2017 16:04:24 +0100 Subject: [PATCH 04/33] - Reverting changes to mpmc queue --- include/spdlog/details/mpmc_bounded_q.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/spdlog/details/mpmc_bounded_q.h b/include/spdlog/details/mpmc_bounded_q.h index c963bc93..3a46e8eb 100644 --- a/include/spdlog/details/mpmc_bounded_q.h +++ b/include/spdlog/details/mpmc_bounded_q.h @@ -159,9 +159,9 @@ private: cell_t* const buffer_; size_t const buffer_mask_; cacheline_pad_t pad1_; - std::atomic enqueue_pos_ {0}; + std::atomic enqueue_pos_; cacheline_pad_t pad2_; - std::atomic dequeue_pos_ {0}; + std::atomic dequeue_pos_; cacheline_pad_t pad3_; mpmc_bounded_queue(mpmc_bounded_queue const&) = delete; From d315bba1f8234b812a025be356a096d0df55da8f Mon Sep 17 00:00:00 2001 From: Oleksii Mandrychenko Date: Wed, 29 Mar 2017 16:06:59 +0100 Subject: [PATCH 05/33] Initialising members via constructor --- include/spdlog/details/logger_impl.h | 8 ++++---- include/spdlog/logger.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/spdlog/details/logger_impl.h b/include/spdlog/details/logger_impl.h index 5bb85f67..c712b27a 100644 --- a/include/spdlog/details/logger_impl.h +++ b/include/spdlog/details/logger_impl.h @@ -18,11 +18,11 @@ template inline spdlog::logger::logger(const std::string& logger_name, const It& begin, const It& end): _name(logger_name), _sinks(begin, end), - _formatter(std::make_shared("%+")) + _formatter(std::make_shared("%+")), + _level(level::info), + _flush_level(level::off), + _last_err_time(0) { - _level = level::info; - _flush_level = level::off; - _last_err_time = 0; _err_handler = [this](const std::string &msg) { this->_default_err_handler(msg); diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index aec1d203..58b4841a 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -87,7 +87,7 @@ protected: spdlog::level_t _level; spdlog::level_t _flush_level; log_err_handler _err_handler; - std::atomic _last_err_time {0}; // init atomic value to avoid reads of uninitialised memory + std::atomic _last_err_time; }; } From a3e84cb347c9d201260712868a2ce456c004c4f7 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Wed, 29 Mar 2017 22:28:37 +0300 Subject: [PATCH 06/33] Update example in README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f5e5fe34..c1a74489 100644 --- a/README.md +++ b/README.md @@ -149,13 +149,13 @@ int main(int, char*[]) err_handler_example(); // Apply a function on all registered loggers - spd::apply_all([&](std::shared_ptr l) + spd::apply_all([&](std::shared_ptr l) { l->info("End of example."); }); // Release and close all loggers - spdlog::drop_all(); + spd::drop_all(); } // Exceptions will only be thrown upon failed logger or sink construction (not during logging) catch (const spd::spdlog_ex& ex) @@ -168,7 +168,7 @@ int main(int, char*[]) void async_example() { size_t q_size = 4096; //queue size must be power of 2 - spdlog::set_async_mode(q_size); + spd::set_async_mode(q_size); auto async_file = spd::daily_logger_st("async_file_logger", "logs/async_log.txt"); for (int i = 0; i < 100; ++i) async_file->info("Async message #{}", i); @@ -206,7 +206,7 @@ void user_defined_example() // void err_handler_example() { - spdlog::set_error_handler([](const std::string& msg) { + spd::set_error_handler([](const std::string& msg) { std::cerr << "my err handler: " << msg << std::endl; }); // (or logger->set_error_handler(..) to set for specific logger) From ea359254d67511aeb897aec53c3c09daf5d9e503 Mon Sep 17 00:00:00 2001 From: odeits Date: Wed, 29 Mar 2017 15:53:14 -0400 Subject: [PATCH 07/33] Fix typo Unkown to Unknown --- include/spdlog/details/os.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index b63ce667..4d9f60a5 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -375,7 +375,7 @@ inline std::string errno_str(int err_num) if(strerror_s(buf, buf_size, err_num) == 0) return std::string(buf); else - return "Unkown error"; + return "Unknown error"; #elif defined(__FreeBSD__) || defined(__APPLE__) || defined(ANDROID) || defined(__SUNPRO_CC) || \ ((_POSIX_C_SOURCE >= 200112L) && ! defined(_GNU_SOURCE)) // posix version @@ -383,7 +383,7 @@ inline std::string errno_str(int err_num) if (strerror_r(err_num, buf, buf_size) == 0) return std::string(buf); else - return "Unkown error"; + return "Unknown error"; #else // gnu version (might not use the given buf, so its retval pointer must be used) return std::string(strerror_r(err_num, buf, buf_size)); From 15af514951d3c2c3ead922d42ae6aab4d01c8bfb Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Sun, 2 Apr 2017 13:05:02 +0300 Subject: [PATCH 08/33] Update file_helper.h --- include/spdlog/details/file_helper.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/spdlog/details/file_helper.h b/include/spdlog/details/file_helper.h index 074d9b83..84ec722d 100644 --- a/include/spdlog/details/file_helper.h +++ b/include/spdlog/details/file_helper.h @@ -7,7 +7,6 @@ // Helper class for file sink // When failing to open a file, retry several times(5) with small delay between the tries(10 ms) -// Can be set to auto flush on every line // Throw spdlog_ex exception on errors #include From 682d2e057f2dab9d2bd32e67ac50d11deda30359 Mon Sep 17 00:00:00 2001 From: odeits Date: Thu, 6 Apr 2017 18:46:52 -0400 Subject: [PATCH 09/33] Fix typo in comment Unkown to Unknown --- include/spdlog/details/pattern_formatter_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/details/pattern_formatter_impl.h b/include/spdlog/details/pattern_formatter_impl.h index 70b9dc80..123024f7 100644 --- a/include/spdlog/details/pattern_formatter_impl.h +++ b/include/spdlog/details/pattern_formatter_impl.h @@ -645,7 +645,7 @@ inline void spdlog::pattern_formatter::handle_flag(char flag) _formatters.push_back(std::unique_ptr(new details::pid_formatter())); break; - default: //Unkown flag appears as is + default: //Unknown flag appears as is _formatters.push_back(std::unique_ptr(new details::ch_formatter('%'))); _formatters.push_back(std::unique_ptr(new details::ch_formatter(flag))); break; From 8d5ecc1b588cdf3aa8ea7bc721f6d10d6b792690 Mon Sep 17 00:00:00 2001 From: odeits Date: Thu, 6 Apr 2017 20:12:11 -0400 Subject: [PATCH 10/33] Fix typo immediatly immediately --- include/spdlog/details/async_log_helper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/details/async_log_helper.h b/include/spdlog/details/async_log_helper.h index f253d364..58eb63f1 100644 --- a/include/spdlog/details/async_log_helper.h +++ b/include/spdlog/details/async_log_helper.h @@ -175,7 +175,7 @@ private: void handle_flush_interval(log_clock::time_point& now, log_clock::time_point& last_flush); - // sleep,yield or return immediatly using the time passed since last message as a hint + // sleep,yield or return immediately using the time passed since last message as a hint static void sleep_or_yield(const spdlog::log_clock::time_point& now, const log_clock::time_point& last_op_time); // wait until the queue is empty From 82404f6f6596c535832a24bde5acfefbfde29d06 Mon Sep 17 00:00:00 2001 From: odeits Date: Thu, 6 Apr 2017 20:13:53 -0400 Subject: [PATCH 11/33] fix typo potentialy to potentially --- include/spdlog/async_logger.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/async_logger.h b/include/spdlog/async_logger.h index 76d70a3d..cda6be4f 100644 --- a/include/spdlog/async_logger.h +++ b/include/spdlog/async_logger.h @@ -61,7 +61,7 @@ public: const std::function& worker_teardown_cb = nullptr); //Wait for the queue to be empty, and flush synchronously - //Warning: this can potentialy last forever as we wait it to complete + //Warning: this can potentially last forever as we wait it to complete void flush() override; // Error handler From 6670d3b925a75363d3bac5dad20b6b064f4e4a57 Mon Sep 17 00:00:00 2001 From: odeits Date: Thu, 6 Apr 2017 20:16:49 -0400 Subject: [PATCH 12/33] fix typos in base_sink.h --- include/spdlog/sinks/base_sink.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/spdlog/sinks/base_sink.h b/include/spdlog/sinks/base_sink.h index 7f1a31db..0a539f32 100644 --- a/include/spdlog/sinks/base_sink.h +++ b/include/spdlog/sinks/base_sink.h @@ -5,8 +5,8 @@ #pragma once // -// base sink templated over a mutex (either dummy or realy) -// concrete implementation should only overrid the _sink_it method. +// base sink templated over a mutex (either dummy or real) +// concrete implementation should only override the _sink_it method. // all locking is taken care of here so no locking needed by the implementers.. // From 45e3e7041d2a2ee1d5e275666b7865e98a6190de Mon Sep 17 00:00:00 2001 From: Amir Cohen Date: Tue, 25 Apr 2017 19:30:11 +0300 Subject: [PATCH 13/33] Android_logger apply its own formatting to every print by adding timestamps, severity, thread and process ids, thus the option flag in the ctor --- include/spdlog/sinks/android_sink.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/spdlog/sinks/android_sink.h b/include/spdlog/sinks/android_sink.h index d8c97e03..0a1bd297 100644 --- a/include/spdlog/sinks/android_sink.h +++ b/include/spdlog/sinks/android_sink.h @@ -25,14 +25,15 @@ namespace sinks class android_sink : public sink { public: - explicit android_sink(const std::string& tag = "spdlog"): _tag(tag) {} + explicit android_sink(const std::string& tag = "spdlog", bool use_raw_msg = false): _tag(tag), _use_raw_msg(use_raw_msg){} void log(const details::log_msg& msg) override { const android_LogPriority priority = convert_to_android(msg.level); + const char *msg_output = (_use_raw_msg ? msg.raw.c_str() : msg.formatted.c_str()); // See system/core/liblog/logger_write.c for explanation of return value const int ret = __android_log_write( - priority, _tag.c_str(), msg.formatted.c_str() + priority, _tag.c_str(), msg_output ); if (ret < 0) { @@ -67,6 +68,7 @@ private: } std::string _tag; + bool _use_raw_msg; }; } From 53138c20fb19991ae62764cff73a802b746ab824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= Date: Fri, 28 Apr 2017 17:24:55 +0200 Subject: [PATCH 14/33] Add an optional final qualifier to types When building with GCC's -Wfinal-types, a lot of types of spdlog are marked as being more optimizable if they were marked final. This patch adds a possibility for the user of the library to `#define SPDLOG_FINAL final` and enjoy potentially better performance : GCC is then able to replace virtual calls by true function calls if it can ensure that there are no derived types). By default SPDLOG_FINAL is defined to nothing to not break existing code that may be inheriting of some of these types for some reason. --- include/spdlog/async_logger.h | 2 +- include/spdlog/common.h | 6 +++ .../spdlog/details/pattern_formatter_impl.h | 52 +++++++++---------- include/spdlog/formatter.h | 2 +- include/spdlog/sinks/ansicolor_sink.h | 2 +- include/spdlog/sinks/base_sink.h | 2 +- include/spdlog/sinks/file_sinks.h | 6 +-- include/spdlog/sinks/stdout_sinks.h | 4 +- 8 files changed, 41 insertions(+), 35 deletions(-) diff --git a/include/spdlog/async_logger.h b/include/spdlog/async_logger.h index cda6be4f..a86d2190 100644 --- a/include/spdlog/async_logger.h +++ b/include/spdlog/async_logger.h @@ -31,7 +31,7 @@ namespace details class async_log_helper; } -class async_logger :public logger +class async_logger SPDLOG_FINAL :public logger { public: template diff --git a/include/spdlog/common.h b/include/spdlog/common.h index a0a227ef..dfecb082 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -29,6 +29,12 @@ #define SPDLOG_CONSTEXPR constexpr #endif +// If an user of the library is not inheriting from the types provided by it, +// he can #define SPDLOG_FINAL final to get additional optimizations +#if !defined(SPDLOG_FINAL) +#define SPDLOG_FINAL +#endif + #if defined(__GNUC__) || defined(__clang__) #define SPDLOG_DEPRECATED __attribute__((deprecated)) #elif defined(_MSC_VER) diff --git a/include/spdlog/details/pattern_formatter_impl.h b/include/spdlog/details/pattern_formatter_impl.h index 123024f7..77f0f20b 100644 --- a/include/spdlog/details/pattern_formatter_impl.h +++ b/include/spdlog/details/pattern_formatter_impl.h @@ -99,7 +99,7 @@ static const days_array& full_days() static const days_array arr{ { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" } }; return arr; } -class A_formatter:public flag_formatter +class A_formatter SPDLOG_FINAL :public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -128,7 +128,7 @@ static const months_array& full_months() static const months_array arr{ { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" } }; return arr; } -class B_formatter:public flag_formatter +class B_formatter SPDLOG_FINAL :public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -153,7 +153,7 @@ static fmt::MemoryWriter& pad_n_join(fmt::MemoryWriter& w, int v1, int v2, int v //Date and time representation (Thu Aug 23 15:35:46 2014) -class c_formatter:public flag_formatter +class c_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -164,7 +164,7 @@ class c_formatter:public flag_formatter // year - 2 digit -class C_formatter:public flag_formatter +class C_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -175,7 +175,7 @@ class C_formatter:public flag_formatter // Short MM/DD/YY date, equivalent to %m/%d/%y 08/23/01 -class D_formatter:public flag_formatter +class D_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -185,7 +185,7 @@ class D_formatter:public flag_formatter // year - 4 digit -class Y_formatter:public flag_formatter +class Y_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -194,7 +194,7 @@ class Y_formatter:public flag_formatter }; // month 1-12 -class m_formatter:public flag_formatter +class m_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -203,7 +203,7 @@ class m_formatter:public flag_formatter }; // day of month 1-31 -class d_formatter:public flag_formatter +class d_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -212,7 +212,7 @@ class d_formatter:public flag_formatter }; // hours in 24 format 0-23 -class H_formatter:public flag_formatter +class H_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -221,7 +221,7 @@ class H_formatter:public flag_formatter }; // hours in 12 format 1-12 -class I_formatter:public flag_formatter +class I_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -230,7 +230,7 @@ class I_formatter:public flag_formatter }; // minutes 0-59 -class M_formatter:public flag_formatter +class M_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -239,7 +239,7 @@ class M_formatter:public flag_formatter }; // seconds 0-59 -class S_formatter:public flag_formatter +class S_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -248,7 +248,7 @@ class S_formatter:public flag_formatter }; // milliseconds -class e_formatter:public flag_formatter +class e_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -259,7 +259,7 @@ class e_formatter:public flag_formatter }; // microseconds -class f_formatter:public flag_formatter +class f_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -270,7 +270,7 @@ class f_formatter:public flag_formatter }; // nanoseconds -class F_formatter:public flag_formatter +class F_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -281,7 +281,7 @@ class F_formatter:public flag_formatter }; // AM/PM -class p_formatter:public flag_formatter +class p_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -291,7 +291,7 @@ class p_formatter:public flag_formatter // 12 hour clock 02:55:02 pm -class r_formatter:public flag_formatter +class r_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -300,7 +300,7 @@ class r_formatter:public flag_formatter }; // 24-hour HH:MM time, equivalent to %H:%M -class R_formatter:public flag_formatter +class R_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -309,7 +309,7 @@ class R_formatter:public flag_formatter }; // ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S -class T_formatter:public flag_formatter +class T_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { @@ -319,7 +319,7 @@ class T_formatter:public flag_formatter // ISO 8601 offset from UTC in timezone (+-HH:MM) -class z_formatter:public flag_formatter +class z_formatter SPDLOG_FINAL:public flag_formatter { public: const std::chrono::seconds cache_refresh = std::chrono::seconds(5); @@ -376,7 +376,7 @@ private: // Thread id -class t_formatter:public flag_formatter +class t_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -385,7 +385,7 @@ class t_formatter:public flag_formatter }; // Current pid -class pid_formatter:public flag_formatter +class pid_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -394,7 +394,7 @@ class pid_formatter:public flag_formatter }; -class v_formatter:public flag_formatter +class v_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm&) override { @@ -402,7 +402,7 @@ class v_formatter:public flag_formatter } }; -class ch_formatter:public flag_formatter +class ch_formatter SPDLOG_FINAL:public flag_formatter { public: explicit ch_formatter(char ch): _ch(ch) @@ -417,7 +417,7 @@ private: //aggregate user chars to display as is -class aggregate_formatter:public flag_formatter +class aggregate_formatter SPDLOG_FINAL:public flag_formatter { public: aggregate_formatter() @@ -436,7 +436,7 @@ private: // Full info formatter // pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v -class full_formatter:public flag_formatter +class full_formatter SPDLOG_FINAL:public flag_formatter { void format(details::log_msg& msg, const std::tm& tm_time) override { diff --git a/include/spdlog/formatter.h b/include/spdlog/formatter.h index 0ffcec03..639cc7d2 100644 --- a/include/spdlog/formatter.h +++ b/include/spdlog/formatter.h @@ -25,7 +25,7 @@ public: virtual void format(details::log_msg& msg) = 0; }; -class pattern_formatter : public formatter +class pattern_formatter SPDLOG_FINAL : public formatter { public: diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index 96e10148..d9df4349 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -21,7 +21,7 @@ namespace sinks * the output with an ANSI escape sequence color code depending on the severity * of the message. */ -class ansicolor_sink : public sink +class ansicolor_sink SPDLOG_FINAL : public sink { public: ansicolor_sink(sink_ptr wrapped_sink); diff --git a/include/spdlog/sinks/base_sink.h b/include/spdlog/sinks/base_sink.h index 0a539f32..c0a910e0 100644 --- a/include/spdlog/sinks/base_sink.h +++ b/include/spdlog/sinks/base_sink.h @@ -31,7 +31,7 @@ public: base_sink(const base_sink&) = delete; base_sink& operator=(const base_sink&) = delete; - void log(const details::log_msg& msg) override + void log(const details::log_msg& msg) SPDLOG_FINAL override { std::lock_guard lock(_mutex); _sink_it(msg); diff --git a/include/spdlog/sinks/file_sinks.h b/include/spdlog/sinks/file_sinks.h index 721a96df..fe40a362 100644 --- a/include/spdlog/sinks/file_sinks.h +++ b/include/spdlog/sinks/file_sinks.h @@ -26,7 +26,7 @@ namespace sinks * Trivial file sink with single file as target */ template -class simple_file_sink : public base_sink < Mutex > +class simple_file_sink SPDLOG_FINAL : public base_sink < Mutex > { public: explicit simple_file_sink(const filename_t &filename, bool truncate = false):_force_flush(false) @@ -61,7 +61,7 @@ typedef simple_file_sink simple_file_sink_st; * Rotating file sink based on size */ template -class rotating_file_sink : public base_sink < Mutex > +class rotating_file_sink SPDLOG_FINAL : public base_sink < Mutex > { public: rotating_file_sink(const filename_t &base_filename, @@ -177,7 +177,7 @@ struct dateonly_daily_file_name_calculator * Rotating file sink based on date. rotates at midnight */ template -class daily_file_sink :public base_sink < Mutex > +class daily_file_sink SPDLOG_FINAL :public base_sink < Mutex > { public: //create daily file sink which rotates on given time diff --git a/include/spdlog/sinks/stdout_sinks.h b/include/spdlog/sinks/stdout_sinks.h index c05f80dd..4dd52ed8 100644 --- a/include/spdlog/sinks/stdout_sinks.h +++ b/include/spdlog/sinks/stdout_sinks.h @@ -18,7 +18,7 @@ namespace sinks { template -class stdout_sink: public base_sink +class stdout_sink SPDLOG_FINAL : public base_sink { using MyType = stdout_sink; public: @@ -47,7 +47,7 @@ typedef stdout_sink stdout_sink_mt; template -class stderr_sink: public base_sink +class stderr_sink SPDLOG_FINAL : public base_sink { using MyType = stderr_sink; public: From 4da5fa256ce6ce330436e3d9850cf35be889f3e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= Date: Fri, 28 Apr 2017 19:25:31 +0200 Subject: [PATCH 15/33] add SPDLOG_FINAL information in tweakme.h --- include/spdlog/common.h | 3 +-- include/spdlog/tweakme.h | 8 ++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/spdlog/common.h b/include/spdlog/common.h index dfecb082..e9fa372e 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -29,8 +29,7 @@ #define SPDLOG_CONSTEXPR constexpr #endif -// If an user of the library is not inheriting from the types provided by it, -// he can #define SPDLOG_FINAL final to get additional optimizations +// See tweakme.h #if !defined(SPDLOG_FINAL) #define SPDLOG_FINAL #endif diff --git a/include/spdlog/tweakme.h b/include/spdlog/tweakme.h index 86f66b9e..bde27967 100644 --- a/include/spdlog/tweakme.h +++ b/include/spdlog/tweakme.h @@ -106,3 +106,11 @@ // // #define SPDLOG_PREVENT_CHILD_FD /////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Uncomment to mark some types as final, allowing more optimizations in release +// mode with recent compilers. See GCC's documentation for -Wsuggest-final-types +// for instance. +// +// #define SPDLOG_FINAL final +/////////////////////////////////////////////////////////////////////////////// From 4a2580231259f464674d8bd998e5fb378694c98d Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Sat, 29 Apr 2017 20:11:54 +0300 Subject: [PATCH 16/33] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c1a74489..6c39596d 100644 --- a/README.md +++ b/README.md @@ -121,11 +121,11 @@ int main(int, char*[]) 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.."); + // 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 From 2f205a6dbc7959403f071c4b610dc811bbda3769 Mon Sep 17 00:00:00 2001 From: Alexander Zilberkant Date: Sun, 30 Apr 2017 23:23:17 +0300 Subject: [PATCH 17/33] android sink - add retry mechanism - in some cases subsequent calls to __android_log_write() may result with -EAGAIN error code. in such cases spdlog will sleep and try again for number of times defined by SPDLOG_ANDROID_LOG_NUM_OF_RETRIES - defeult SPDLOG_ANDROID_LOG_NUM_OF_RETRIES set to 2 - can be overridden at build time --- include/spdlog/sinks/android_sink.h | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/include/spdlog/sinks/android_sink.h b/include/spdlog/sinks/android_sink.h index 0a1bd297..afc7a547 100644 --- a/include/spdlog/sinks/android_sink.h +++ b/include/spdlog/sinks/android_sink.h @@ -12,6 +12,12 @@ #include #include #include +#include +#include + +#if !defined(SPDLOG_ANDROID_LOG_NUM_OF_RETRIES) +define SPDLOG_ANDROID_LOG_NUM_OF_RETRIES 2 +#endif namespace spdlog { @@ -31,10 +37,17 @@ public: { const android_LogPriority priority = convert_to_android(msg.level); const char *msg_output = (_use_raw_msg ? msg.raw.c_str() : msg.formatted.c_str()); + // See system/core/liblog/logger_write.c for explanation of return value - const int ret = __android_log_write( - priority, _tag.c_str(), msg_output - ); + int ret = __android_log_write(priority, _tag.c_str(), msg_output); + int retry_count = 1; + while ((ret == -11/*EAGAIN*/) && (retry_count < SPDLOG_ANDROID_LOG_NUM_OF_RETRIES)) + { + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + ret = __android_log_write(priority, _tag.c_str(), msg_output); + retry_count++; + } + if (ret < 0) { throw spdlog_ex("__android_log_write() failed", ret); From 6927aa1544508d8b223845e25e6f848db2a3f5a7 Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Wed, 3 May 2017 01:17:00 +0300 Subject: [PATCH 18/33] Update android_sink.h --- include/spdlog/sinks/android_sink.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/spdlog/sinks/android_sink.h b/include/spdlog/sinks/android_sink.h index afc7a547..26431829 100644 --- a/include/spdlog/sinks/android_sink.h +++ b/include/spdlog/sinks/android_sink.h @@ -16,7 +16,7 @@ #include #if !defined(SPDLOG_ANDROID_LOG_NUM_OF_RETRIES) -define SPDLOG_ANDROID_LOG_NUM_OF_RETRIES 2 +#define SPDLOG_ANDROID_RETRIES 2 #endif namespace spdlog @@ -40,8 +40,8 @@ public: // See system/core/liblog/logger_write.c for explanation of return value int ret = __android_log_write(priority, _tag.c_str(), msg_output); - int retry_count = 1; - while ((ret == -11/*EAGAIN*/) && (retry_count < SPDLOG_ANDROID_LOG_NUM_OF_RETRIES)) + int retry_count = 0; + while ((ret == -11/*EAGAIN*/) && (retry_count < SPDLOG_ANDROID_RETRIES)) { std::this_thread::sleep_for(std::chrono::milliseconds(5)); ret = __android_log_write(priority, _tag.c_str(), msg_output); From 52292fb5264b51b383721e013ad621a6d9534c37 Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Wed, 3 May 2017 01:18:40 +0300 Subject: [PATCH 19/33] Update android_sink.h --- include/spdlog/sinks/android_sink.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/sinks/android_sink.h b/include/spdlog/sinks/android_sink.h index 26431829..d38133d6 100644 --- a/include/spdlog/sinks/android_sink.h +++ b/include/spdlog/sinks/android_sink.h @@ -15,7 +15,7 @@ #include #include -#if !defined(SPDLOG_ANDROID_LOG_NUM_OF_RETRIES) +#if !defined(SPDLOG_ANDROID_RETRIES) #define SPDLOG_ANDROID_RETRIES 2 #endif From 81965bc300eebb051ec22adf5d0df7f34dc6c67c Mon Sep 17 00:00:00 2001 From: gabime Date: Sat, 6 May 2017 15:33:12 +0300 Subject: [PATCH 20/33] Fixed some analyzer warnings --- include/spdlog/details/async_log_helper.h | 6 +++++- include/spdlog/details/pattern_formatter_impl.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/spdlog/details/async_log_helper.h b/include/spdlog/details/async_log_helper.h index 58eb63f1..1e454550 100644 --- a/include/spdlog/details/async_log_helper.h +++ b/include/spdlog/details/async_log_helper.h @@ -60,11 +60,15 @@ async_msg(async_msg&& other) SPDLOG_NOEXCEPT: logger_name(std::move(other.logger_name)), level(std::move(other.level)), time(std::move(other.time)), + thread_id(other.thread_id), txt(std::move(other.txt)), msg_type(std::move(other.msg_type)) {} - async_msg(async_msg_type m_type):msg_type(m_type) + async_msg(async_msg_type m_type): + level(level::info), + thread_id(0), + msg_type(m_type) {} async_msg& operator=(async_msg&& other) SPDLOG_NOEXCEPT diff --git a/include/spdlog/details/pattern_formatter_impl.h b/include/spdlog/details/pattern_formatter_impl.h index 123024f7..49e8320d 100644 --- a/include/spdlog/details/pattern_formatter_impl.h +++ b/include/spdlog/details/pattern_formatter_impl.h @@ -324,7 +324,7 @@ class z_formatter:public flag_formatter public: const std::chrono::seconds cache_refresh = std::chrono::seconds(5); - z_formatter():_last_update(std::chrono::seconds(0)) + z_formatter():_last_update(std::chrono::seconds(0)), _offset_minutes(0) {} z_formatter(const z_formatter&) = delete; z_formatter& operator=(const z_formatter&) = delete; From 84a4f56eaeec8acfb96b4ee635a5e413e596d4b9 Mon Sep 17 00:00:00 2001 From: Barrett Date: Tue, 9 May 2017 18:31:44 -0700 Subject: [PATCH 21/33] Allow compiler to select an strerror_r stringify On Alpine (and potentially other systems) that don't identify their runtime correctly there is an issue with the string conversion Specifically, alpine linux and musl where the errno_to_string is incorrectly called. To fix this I have added two overloaded functions and use auto err to allow the compiler to detect the actual types returned and call the correct method for conversion --- include/spdlog/details/os.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 4d9f60a5..afb56971 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -364,6 +364,17 @@ inline std::string filename_to_str(const filename_t& filename) } #endif +inline std::string errno_to_string(char [256], char* res) { + return std::string(res); +} + +inline std::string errno_to_string(char buf[256], int res) { + if (res == 0) { + return std::string(buf); + } else { + return "Unknown error"; + } +} // Return errno string (thread safe) inline std::string errno_str(int err_num) @@ -386,7 +397,8 @@ inline std::string errno_str(int err_num) return "Unknown error"; #else // gnu version (might not use the given buf, so its retval pointer must be used) - return std::string(strerror_r(err_num, buf, buf_size)); + auto err = strerror_r(err_num, buf, buf_size); // let compiler choose type + return errno_to_string(buf, err); // use overloading to select correct stringify function #endif } From 8ee6d38501529957d1183969a9068505d825cf81 Mon Sep 17 00:00:00 2001 From: Sidyhe Date: Sat, 1 Apr 2017 23:37:16 +0800 Subject: [PATCH 22/33] add wide string to utf8 string support --- include/spdlog/details/logger_impl.h | 57 ++++++++++++++++++++++++++++ include/spdlog/logger.h | 10 +++++ include/spdlog/tweakme.h | 6 +++ 3 files changed, 73 insertions(+) diff --git a/include/spdlog/details/logger_impl.h b/include/spdlog/details/logger_impl.h index c712b27a..cf65f31b 100644 --- a/include/spdlog/details/logger_impl.h +++ b/include/spdlog/details/logger_impl.h @@ -195,6 +195,63 @@ inline void spdlog::logger::critical(const T& msg) log(level::critical, msg); } +#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT +#include + +template +inline void spdlog::logger::log(level::level_enum lvl, const wchar_t* msg) +{ + std::wstring_convert > conv; + + log(lvl, conv.to_bytes(msg)); +} + +template +inline void spdlog::logger::log(level::level_enum lvl, const wchar_t* fmt, const Args&... args) +{ + fmt::WMemoryWriter wWriter; + + wWriter.write(fmt, args...); + log(lvl, wWriter.c_str()); +} + +template +inline void spdlog::logger::trace(const wchar_t* fmt, const Args&... args) +{ + log(level::trace, fmt, args...); +} + +template +inline void spdlog::logger::debug(const wchar_t* fmt, const Args&... args) +{ + log(level::debug, fmt, args...); +} + +template +inline void spdlog::logger::info(const wchar_t* fmt, const Args&... args) +{ + log(level::info, fmt, args...); +} + + +template +inline void spdlog::logger::warn(const wchar_t* fmt, const Args&... args) +{ + log(level::warn, fmt, args...); +} + +template +inline void spdlog::logger::error(const wchar_t* fmt, const Args&... args) +{ + log(level::err, fmt, args...); +} + +template +inline void spdlog::logger::critical(const wchar_t* fmt, const Args&... args) +{ + log(level::critical, fmt, args...); +} +#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index 58b4841a..0c864f9e 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -43,6 +43,16 @@ public: template void warn(const char* fmt, const Arg1&, const Args&... args); template void error(const char* fmt, const Arg1&, const Args&... args); template void critical(const char* fmt, const Arg1&, const Args&... args); +#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT + template void log(level::level_enum lvl, const wchar_t* msg); + template void log(level::level_enum lvl, const wchar_t* fmt, const Args&... args); + template void trace(const wchar_t* fmt, const Args&... args); + template void debug(const wchar_t* fmt, const Args&... args); + template void info(const wchar_t* fmt, const Args&... args); + template void warn(const wchar_t* fmt, const Args&... args); + template void error(const wchar_t* fmt, const Args&... args); + template void critical(const wchar_t* fmt, const Args&... args); +#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT template void log(level::level_enum lvl, const T&); template void trace(const T&); diff --git a/include/spdlog/tweakme.h b/include/spdlog/tweakme.h index bde27967..c167c716 100644 --- a/include/spdlog/tweakme.h +++ b/include/spdlog/tweakme.h @@ -101,6 +101,12 @@ /////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// Uncomment to enable wchar_t support (convert to utf8) +// +// #define SPDLOG_WCHAR_TO_UTF8_SUPPORT +/////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// // Uncomment to prevent child processes from inheriting log file descriptors // From 0aeaf9e28e080c4cc1754571370b9e0654c7137f Mon Sep 17 00:00:00 2001 From: Alexander Zilberkant Date: Thu, 11 May 2017 23:52:42 +0300 Subject: [PATCH 23/33] add an option to warn about discarded messages when using async_logger with async_overflow_policy::discard_log_msg each discarded message will be counted and warning will be printed by the worker thread this new feature is disabled by default - as it may have a performance hit when discarding messages --- include/spdlog/details/async_log_helper.h | 42 ++++++++++++++++++----- include/spdlog/tweakme.h | 7 ++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/include/spdlog/details/async_log_helper.h b/include/spdlog/details/async_log_helper.h index 1e454550..2b5e382e 100644 --- a/include/spdlog/details/async_log_helper.h +++ b/include/spdlog/details/async_log_helper.h @@ -27,6 +27,7 @@ #include #include #include +#include namespace spdlog { @@ -185,6 +186,9 @@ private: // wait until the queue is empty void wait_empty_q(); + // counter for messages discarded due to queue overflow + std::atomic _discarded_msg_count; + }; } } @@ -211,7 +215,8 @@ inline spdlog::details::async_log_helper::async_log_helper( _worker_warmup_cb(worker_warmup_cb), _flush_interval_ms(flush_interval_ms), _worker_teardown_cb(worker_teardown_cb), - _worker_thread(&async_log_helper::worker_loop, this) + _worker_thread(&async_log_helper::worker_loop, this), + _discarded_msg_count(0) {} // Send to the worker thread termination message(level=off) @@ -237,16 +242,24 @@ inline void spdlog::details::async_log_helper::log(const details::log_msg& msg) inline void spdlog::details::async_log_helper::push_msg(details::async_log_helper::async_msg&& new_msg) { - if (!_q.enqueue(std::move(new_msg)) && _overflow_policy != async_overflow_policy::discard_log_msg) + if (!_q.enqueue(std::move(new_msg))) { - auto last_op_time = details::os::now(); - auto now = last_op_time; - do + if (_overflow_policy != async_overflow_policy::discard_log_msg) + { + auto last_op_time = details::os::now(); + auto now = last_op_time; + do + { + now = details::os::now(); + sleep_or_yield(now, last_op_time); + } while (!_q.enqueue(std::move(new_msg))); + } + else { - now = details::os::now(); - sleep_or_yield(now, last_op_time); +#if defined(SPDLOG_ASYNC_COUNT_DISCARDED_MSG) + _discarded_msg_count++; +#endif } - while (!_q.enqueue(std::move(new_msg))); } } @@ -305,6 +318,19 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_ break; default: +#if defined(SPDLOG_ASYNC_COUNT_DISCARDED_MSG) + unsigned int num_of_discarded_messages = _discarded_msg_count.exchange(0); + if (num_of_discarded_messages) + { + log_msg discarded_warning_msg(&incoming_async_msg.logger_name, level::warn); + discarded_warning_msg.raw << "Dropped " << num_of_discarded_messages << " messages"; + for (auto &s : _sinks) + { + s->log(discarded_warning_msg); + } + } +#endif + log_msg incoming_log_msg; incoming_async_msg.fill_log_msg(incoming_log_msg); _formatter->format(incoming_log_msg); diff --git a/include/spdlog/tweakme.h b/include/spdlog/tweakme.h index bde27967..0f3c2763 100644 --- a/include/spdlog/tweakme.h +++ b/include/spdlog/tweakme.h @@ -114,3 +114,10 @@ // // #define SPDLOG_FINAL final /////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Uncomment count in print warning message about number of dropped messages. +// Only relevant for async_logger with async_overflow_policy::discard_log_msg +// +#define SPDLOG_ASYNC_COUNT_DISCARDED_MSG +/////////////////////////////////////////////////////////////////////////////// From 42258a1059645e2c264a0caa8aa737d2e13d0c80 Mon Sep 17 00:00:00 2001 From: Alexander Zilberkant Date: Sat, 13 May 2017 00:53:57 +0300 Subject: [PATCH 24/33] move discarded message handling to a dedicated function fix - formatter new discarded message --- include/spdlog/details/async_log_helper.h | 29 ++++++++++++++--------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/include/spdlog/details/async_log_helper.h b/include/spdlog/details/async_log_helper.h index 2b5e382e..c5a147ec 100644 --- a/include/spdlog/details/async_log_helper.h +++ b/include/spdlog/details/async_log_helper.h @@ -189,6 +189,9 @@ private: // counter for messages discarded due to queue overflow std::atomic _discarded_msg_count; + // handle discarded messages + void handle_discarded_msg(const std::string& logger_name); + }; } } @@ -319,16 +322,7 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_ default: #if defined(SPDLOG_ASYNC_COUNT_DISCARDED_MSG) - unsigned int num_of_discarded_messages = _discarded_msg_count.exchange(0); - if (num_of_discarded_messages) - { - log_msg discarded_warning_msg(&incoming_async_msg.logger_name, level::warn); - discarded_warning_msg.raw << "Dropped " << num_of_discarded_messages << " messages"; - for (auto &s : _sinks) - { - s->log(discarded_warning_msg); - } - } + handle_discarded_msg(incoming_async_msg.logger_name); #endif log_msg incoming_log_msg; @@ -415,5 +409,18 @@ inline void spdlog::details::async_log_helper::set_error_handler(spdlog::log_err _err_handler = err_handler; } - +inline void spdlog::details::async_log_helper::handle_discarded_msg(const std::string& logger_name) +{ + unsigned int num_of_discarded_messages = _discarded_msg_count.exchange(0); + if (num_of_discarded_messages) + { + log_msg discarded_warning_msg(&logger_name, level::warn); + discarded_warning_msg.raw << "Discarded " << num_of_discarded_messages << " messages - logger queue overflow"; + _formatter->format(discarded_warning_msg); + for (auto &s : _sinks) + { + s->log(discarded_warning_msg); + } + } +} From 0f25b25b20908a89495809b062cef71920d887e5 Mon Sep 17 00:00:00 2001 From: Alexander Zilberkant Date: Sat, 13 May 2017 01:01:28 +0300 Subject: [PATCH 25/33] add async_logger tests cover discarded messages use-case --- tests/CMakeLists.txt | 2 +- tests/async_logger.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/async_logger.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ce275ccb..22329b4e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,7 +10,7 @@ find_package(Threads) add_library(catch INTERFACE) target_include_directories(catch INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -file(GLOB catch_tests LIST_DIRECTORIES false RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) +file(GLOB catch_tests LIST_DIRECTORIES false RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp *.h *.hpp) add_executable(catch_tests ${catch_tests}) target_link_libraries(catch_tests spdlog ${CMAKE_THREAD_LIBS_INIT}) diff --git a/tests/async_logger.cpp b/tests/async_logger.cpp new file mode 100644 index 00000000..bcfb1ca6 --- /dev/null +++ b/tests/async_logger.cpp @@ -0,0 +1,38 @@ + +#include + +#include "includes.h" +#include "../include/spdlog/common.h" +#include "../include/spdlog/tweakme.h" + + +TEST_CASE("async_logging_overflow ", "[async_logging]") +{ + std::string filename = "logs/async_log_overflow.txt"; + auto sink = std::make_shared(filename, true); + auto logger = std::make_shared( + "overflow_logger", + sink, + 2, // queue size + spdlog::async_overflow_policy::discard_log_msg + ); + for (int i = 0; i < 8; i++) { + logger->info("Message #{}", i); + } + logger->flush(); + logger.reset(); + std::string the_log = file_contents(filename); +#if defined(SPDLOG_ASYNC_COUNT_DISCARDED_MSG) + std::cout << the_log << std::endl; + REQUIRE(the_log.find("Dropped 6 messages") != std::string::npos); +#endif +} + + + + + + + + + From 2b008efb0696e7cdd5271f28824e9652b80a28d6 Mon Sep 17 00:00:00 2001 From: Alexander Zilberkant Date: Sat, 13 May 2017 01:10:58 +0300 Subject: [PATCH 26/33] disable SPDLOG_ASYNC_COUNT_DISCARDED_MSG --- include/spdlog/tweakme.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/tweakme.h b/include/spdlog/tweakme.h index 0f3c2763..99b8f4dd 100644 --- a/include/spdlog/tweakme.h +++ b/include/spdlog/tweakme.h @@ -119,5 +119,5 @@ // Uncomment count in print warning message about number of dropped messages. // Only relevant for async_logger with async_overflow_policy::discard_log_msg // -#define SPDLOG_ASYNC_COUNT_DISCARDED_MSG +// #define SPDLOG_ASYNC_COUNT_DISCARDED_MSG /////////////////////////////////////////////////////////////////////////////// From 13199034f0c8c670dd653882622f413927a32401 Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Sat, 13 May 2017 01:25:48 +0300 Subject: [PATCH 27/33] Update tweakme.h --- include/spdlog/tweakme.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/tweakme.h b/include/spdlog/tweakme.h index e568d301..f1d25be6 100644 --- a/include/spdlog/tweakme.h +++ b/include/spdlog/tweakme.h @@ -122,7 +122,7 @@ /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// -// Uncomment count in print warning message about number of dropped messages. +// Uncomment to count and print warning message about number of dropped messages. // Only relevant for async_logger with async_overflow_policy::discard_log_msg // // #define SPDLOG_ASYNC_COUNT_DISCARDED_MSG From 6547675e4376ae821d99adb4a1bd80c117a175ee Mon Sep 17 00:00:00 2001 From: Alexander Zilberkant Date: Mon, 15 May 2017 20:07:24 +0300 Subject: [PATCH 28/33] Revert "Merge pull request #441 from alzix/count_discarded" This reverts commit 038733345a44aca8ce3baf1ce19e57d7844e22ee, reversing changes made to 862d2f6f3549aa64404b2a3fbfd1b0a637f7e093. --- include/spdlog/details/async_log_helper.h | 51 ++++------------------- include/spdlog/tweakme.h | 7 ---- tests/async_logger.cpp | 38 ----------------- 3 files changed, 9 insertions(+), 87 deletions(-) delete mode 100644 tests/async_logger.cpp diff --git a/include/spdlog/details/async_log_helper.h b/include/spdlog/details/async_log_helper.h index c5a147ec..1e454550 100644 --- a/include/spdlog/details/async_log_helper.h +++ b/include/spdlog/details/async_log_helper.h @@ -27,7 +27,6 @@ #include #include #include -#include namespace spdlog { @@ -186,12 +185,6 @@ private: // wait until the queue is empty void wait_empty_q(); - // counter for messages discarded due to queue overflow - std::atomic _discarded_msg_count; - - // handle discarded messages - void handle_discarded_msg(const std::string& logger_name); - }; } } @@ -218,8 +211,7 @@ inline spdlog::details::async_log_helper::async_log_helper( _worker_warmup_cb(worker_warmup_cb), _flush_interval_ms(flush_interval_ms), _worker_teardown_cb(worker_teardown_cb), - _worker_thread(&async_log_helper::worker_loop, this), - _discarded_msg_count(0) + _worker_thread(&async_log_helper::worker_loop, this) {} // Send to the worker thread termination message(level=off) @@ -245,24 +237,16 @@ inline void spdlog::details::async_log_helper::log(const details::log_msg& msg) inline void spdlog::details::async_log_helper::push_msg(details::async_log_helper::async_msg&& new_msg) { - if (!_q.enqueue(std::move(new_msg))) + if (!_q.enqueue(std::move(new_msg)) && _overflow_policy != async_overflow_policy::discard_log_msg) { - if (_overflow_policy != async_overflow_policy::discard_log_msg) - { - auto last_op_time = details::os::now(); - auto now = last_op_time; - do - { - now = details::os::now(); - sleep_or_yield(now, last_op_time); - } while (!_q.enqueue(std::move(new_msg))); - } - else + auto last_op_time = details::os::now(); + auto now = last_op_time; + do { -#if defined(SPDLOG_ASYNC_COUNT_DISCARDED_MSG) - _discarded_msg_count++; -#endif + now = details::os::now(); + sleep_or_yield(now, last_op_time); } + while (!_q.enqueue(std::move(new_msg))); } } @@ -321,10 +305,6 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_ break; default: -#if defined(SPDLOG_ASYNC_COUNT_DISCARDED_MSG) - handle_discarded_msg(incoming_async_msg.logger_name); -#endif - log_msg incoming_log_msg; incoming_async_msg.fill_log_msg(incoming_log_msg); _formatter->format(incoming_log_msg); @@ -409,18 +389,5 @@ inline void spdlog::details::async_log_helper::set_error_handler(spdlog::log_err _err_handler = err_handler; } -inline void spdlog::details::async_log_helper::handle_discarded_msg(const std::string& logger_name) -{ - unsigned int num_of_discarded_messages = _discarded_msg_count.exchange(0); - if (num_of_discarded_messages) - { - log_msg discarded_warning_msg(&logger_name, level::warn); - discarded_warning_msg.raw << "Discarded " << num_of_discarded_messages << " messages - logger queue overflow"; - _formatter->format(discarded_warning_msg); - for (auto &s : _sinks) - { - s->log(discarded_warning_msg); - } - } -} + diff --git a/include/spdlog/tweakme.h b/include/spdlog/tweakme.h index f1d25be6..c167c716 100644 --- a/include/spdlog/tweakme.h +++ b/include/spdlog/tweakme.h @@ -120,10 +120,3 @@ // // #define SPDLOG_FINAL final /////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// Uncomment to count and print warning message about number of dropped messages. -// Only relevant for async_logger with async_overflow_policy::discard_log_msg -// -// #define SPDLOG_ASYNC_COUNT_DISCARDED_MSG -/////////////////////////////////////////////////////////////////////////////// diff --git a/tests/async_logger.cpp b/tests/async_logger.cpp deleted file mode 100644 index bcfb1ca6..00000000 --- a/tests/async_logger.cpp +++ /dev/null @@ -1,38 +0,0 @@ - -#include - -#include "includes.h" -#include "../include/spdlog/common.h" -#include "../include/spdlog/tweakme.h" - - -TEST_CASE("async_logging_overflow ", "[async_logging]") -{ - std::string filename = "logs/async_log_overflow.txt"; - auto sink = std::make_shared(filename, true); - auto logger = std::make_shared( - "overflow_logger", - sink, - 2, // queue size - spdlog::async_overflow_policy::discard_log_msg - ); - for (int i = 0; i < 8; i++) { - logger->info("Message #{}", i); - } - logger->flush(); - logger.reset(); - std::string the_log = file_contents(filename); -#if defined(SPDLOG_ASYNC_COUNT_DISCARDED_MSG) - std::cout << the_log << std::endl; - REQUIRE(the_log.find("Dropped 6 messages") != std::string::npos); -#endif -} - - - - - - - - - From 8329d97d9027651022bea278f3ddf864f60d5630 Mon Sep 17 00:00:00 2001 From: Alexander Zilberkant Date: Sat, 13 May 2017 18:57:56 +0300 Subject: [PATCH 29/33] fix indentation --- include/spdlog/details/async_log_helper.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/spdlog/details/async_log_helper.h b/include/spdlog/details/async_log_helper.h index c5a147ec..f174955a 100644 --- a/include/spdlog/details/async_log_helper.h +++ b/include/spdlog/details/async_log_helper.h @@ -57,19 +57,19 @@ class async_log_helper ~async_msg() = default; -async_msg(async_msg&& other) SPDLOG_NOEXCEPT: - logger_name(std::move(other.logger_name)), - level(std::move(other.level)), - time(std::move(other.time)), - thread_id(other.thread_id), - txt(std::move(other.txt)), - msg_type(std::move(other.msg_type)) + async_msg(async_msg&& other) SPDLOG_NOEXCEPT: + logger_name(std::move(other.logger_name)), + level(std::move(other.level)), + time(std::move(other.time)), + thread_id(other.thread_id), + txt(std::move(other.txt)), + msg_type(std::move(other.msg_type)) {} async_msg(async_msg_type m_type): - level(level::info), - thread_id(0), - msg_type(m_type) + level(level::info), + thread_id(0), + msg_type(m_type) {} async_msg& operator=(async_msg&& other) SPDLOG_NOEXCEPT From bd25f59a423ac40a0eba4206ad295b3e2cef7dfc Mon Sep 17 00:00:00 2001 From: gabime Date: Tue, 16 May 2017 23:35:01 +0300 Subject: [PATCH 30/33] Don't use color escape codes if terminal doesn't support them in ansicolor_sink --- include/spdlog/details/os.h | 27 ++++ include/spdlog/sinks/ansicolor_sink.h | 207 ++++++++++++++------------ 2 files changed, 135 insertions(+), 99 deletions(-) diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 4d9f60a5..637962a8 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -401,6 +402,32 @@ inline int pid() } + +// Detrmine if the terminal supports colors +// Source: https://github.com/agauniyal/rang/ +bool is_color_terminal() +{ +#ifdef _WIN32 + return true; +#else + static constexpr const char* Terms[] = { + "ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", + "linux", "msys", "putty", "rxvt", "screen", "vt100", "xterm" + }; + + const char *env_p = std::getenv("TERM"); + if (env_p == nullptr) { + return false; + } + + static const bool result = std::any_of( + std::begin(Terms), std::end(Terms), [&](const char* term) { + return std::strstr(env_p, term) != nullptr; + }); +#endif +} + + } //os } //details } //spdlog diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index d9df4349..33d02445 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -7,110 +7,119 @@ #include #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 SPDLOG_FINAL : 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 color_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] = bold; - colors_[level::warn] = yellow + bold; - colors_[level::err] = red + bold; - colors_[level::critical] = bold + 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.level = msg.level; - m.logger_name = msg.logger_name; - m.time = msg.time; - m.thread_id = msg.thread_id; - m.formatted << prefix << s << suffix; - sink_->log(m); -} - -inline void ansicolor_sink::flush() -{ - sink_->flush(); -} - -inline void ansicolor_sink::set_color(level::level_enum color_level, const std::string& color) -{ - colors_[color_level] = color; -} - -inline ansicolor_sink::~ansicolor_sink() -{ - flush(); -} - -} // namespace sinks + 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 SPDLOG_FINAL: 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 color_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: + bool is_color_terminal_; + sink_ptr sink_; + std::map colors_; + }; + + inline ansicolor_sink::ansicolor_sink(sink_ptr wrapped_sink): sink_(wrapped_sink) + { + is_color_terminal_ = details::os::is_color_terminal(); + colors_[level::trace] = cyan; + colors_[level::debug] = cyan; + colors_[level::info] = bold; + colors_[level::warn] = yellow + bold; + colors_[level::err] = red + bold; + colors_[level::critical] = bold + on_red; + colors_[level::off] = reset; + } + + inline void ansicolor_sink::log(const details::log_msg& msg) + { + // Wrap the originally formatted message in color codes. + // If color is not supported in the terminal, log as is instead. + if (is_color_terminal_) { + const std::string& prefix = colors_[msg.level]; + const std::string& s = msg.formatted.str(); + const std::string& suffix = reset; + details::log_msg m; + m.level = msg.level; + m.logger_name = msg.logger_name; + m.time = msg.time; + m.thread_id = msg.thread_id; + m.formatted << prefix << s << suffix; + sink_->log(m); + } + else { + sink_->log(msg); + } + } + + inline void ansicolor_sink::flush() + { + sink_->flush(); + } + + inline void ansicolor_sink::set_color(level::level_enum color_level, const std::string& color) + { + colors_[color_level] = color; + } + + inline ansicolor_sink::~ansicolor_sink() + { + flush(); + } + + } // namespace sinks } // namespace spdlog From 1d6842f0f9833db265355fef110a15e596769362 Mon Sep 17 00:00:00 2001 From: gabime Date: Wed, 17 May 2017 00:06:11 +0300 Subject: [PATCH 31/33] bugfix in color detection and astyle --- include/spdlog/details/async_log_helper.h | 14 +- include/spdlog/details/logger_impl.h | 28 +-- include/spdlog/details/os.h | 55 +++--- include/spdlog/logger.h | 16 +- include/spdlog/sinks/android_sink.h | 2 +- include/spdlog/sinks/ansicolor_sink.h | 216 +++++++++++----------- 6 files changed, 171 insertions(+), 160 deletions(-) diff --git a/include/spdlog/details/async_log_helper.h b/include/spdlog/details/async_log_helper.h index a95ccff2..faa23cbe 100644 --- a/include/spdlog/details/async_log_helper.h +++ b/include/spdlog/details/async_log_helper.h @@ -56,13 +56,13 @@ class async_log_helper ~async_msg() = default; - async_msg(async_msg&& other) SPDLOG_NOEXCEPT: - logger_name(std::move(other.logger_name)), - level(std::move(other.level)), - time(std::move(other.time)), - thread_id(other.thread_id), - txt(std::move(other.txt)), - msg_type(std::move(other.msg_type)) +async_msg(async_msg&& other) SPDLOG_NOEXCEPT: + logger_name(std::move(other.logger_name)), + level(std::move(other.level)), + time(std::move(other.time)), + thread_id(other.thread_id), + txt(std::move(other.txt)), + msg_type(std::move(other.msg_type)) {} async_msg(async_msg_type m_type): diff --git a/include/spdlog/details/logger_impl.h b/include/spdlog/details/logger_impl.h index cf65f31b..02ebc875 100644 --- a/include/spdlog/details/logger_impl.h +++ b/include/spdlog/details/logger_impl.h @@ -19,9 +19,9 @@ inline spdlog::logger::logger(const std::string& logger_name, const It& begin, c _name(logger_name), _sinks(begin, end), _formatter(std::make_shared("%+")), - _level(level::info), - _flush_level(level::off), - _last_err_time(0) + _level(level::info), + _flush_level(level::off), + _last_err_time(0) { _err_handler = [this](const std::string &msg) { @@ -201,55 +201,55 @@ inline void spdlog::logger::critical(const T& msg) template inline void spdlog::logger::log(level::level_enum lvl, const wchar_t* msg) { - std::wstring_convert > conv; + std::wstring_convert > conv; - log(lvl, conv.to_bytes(msg)); + log(lvl, conv.to_bytes(msg)); } template inline void spdlog::logger::log(level::level_enum lvl, const wchar_t* fmt, const Args&... args) { - fmt::WMemoryWriter wWriter; + fmt::WMemoryWriter wWriter; - wWriter.write(fmt, args...); - log(lvl, wWriter.c_str()); + wWriter.write(fmt, args...); + log(lvl, wWriter.c_str()); } template inline void spdlog::logger::trace(const wchar_t* fmt, const Args&... args) { - log(level::trace, fmt, args...); + log(level::trace, fmt, args...); } template inline void spdlog::logger::debug(const wchar_t* fmt, const Args&... args) { - log(level::debug, fmt, args...); + log(level::debug, fmt, args...); } template inline void spdlog::logger::info(const wchar_t* fmt, const Args&... args) { - log(level::info, fmt, args...); + log(level::info, fmt, args...); } template inline void spdlog::logger::warn(const wchar_t* fmt, const Args&... args) { - log(level::warn, fmt, args...); + log(level::warn, fmt, args...); } template inline void spdlog::logger::error(const wchar_t* fmt, const Args&... args) { - log(level::err, fmt, args...); + log(level::err, fmt, args...); } template inline void spdlog::logger::critical(const wchar_t* fmt, const Args&... args) { - log(level::critical, fmt, args...); + log(level::critical, fmt, args...); } #endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 1e557c89..83700666 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -365,14 +365,19 @@ inline std::string filename_to_str(const filename_t& filename) } #endif -inline std::string errno_to_string(char [256], char* res) { +inline std::string errno_to_string(char [256], char* res) +{ return std::string(res); } - -inline std::string errno_to_string(char buf[256], int res) { - if (res == 0) { + +inline std::string errno_to_string(char buf[256], int res) +{ + if (res == 0) + { return std::string(buf); - } else { + } + else + { return "Unknown error"; } } @@ -419,24 +424,28 @@ inline int pid() // Source: https://github.com/agauniyal/rang/ bool is_color_terminal() { -#ifdef _WIN32 - return true; -#else - static constexpr const char* Terms[] = { - "ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", - "linux", "msys", "putty", "rxvt", "screen", "vt100", "xterm" - }; - - const char *env_p = std::getenv("TERM"); - if (env_p == nullptr) { - return false; - } - - static const bool result = std::any_of( - std::begin(Terms), std::end(Terms), [&](const char* term) { - return std::strstr(env_p, term) != nullptr; - }); -#endif +#ifdef _WIN32 + return true; +#else + static constexpr const char* Terms[] = + { + "ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", + "linux", "msys", "putty", "rxvt", "screen", "vt100", "xterm" + }; + + const char *env_p = std::getenv("TERM"); + if (env_p == nullptr) + { + return false; + } + + static const bool result = std::any_of( + std::begin(Terms), std::end(Terms), [&](const char* term) + { + return std::strstr(env_p, term) != nullptr; + }); + return result; +#endif } diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index 0c864f9e..af6f93fd 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -44,14 +44,14 @@ public: template void error(const char* fmt, const Arg1&, const Args&... args); template void critical(const char* fmt, const Arg1&, const Args&... args); #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT - template void log(level::level_enum lvl, const wchar_t* msg); - template void log(level::level_enum lvl, const wchar_t* fmt, const Args&... args); - template void trace(const wchar_t* fmt, const Args&... args); - template void debug(const wchar_t* fmt, const Args&... args); - template void info(const wchar_t* fmt, const Args&... args); - template void warn(const wchar_t* fmt, const Args&... args); - template void error(const wchar_t* fmt, const Args&... args); - template void critical(const wchar_t* fmt, const Args&... args); + template void log(level::level_enum lvl, const wchar_t* msg); + template void log(level::level_enum lvl, const wchar_t* fmt, const Args&... args); + template void trace(const wchar_t* fmt, const Args&... args); + template void debug(const wchar_t* fmt, const Args&... args); + template void info(const wchar_t* fmt, const Args&... args); + template void warn(const wchar_t* fmt, const Args&... args); + template void error(const wchar_t* fmt, const Args&... args); + template void critical(const wchar_t* fmt, const Args&... args); #endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT template void log(level::level_enum lvl, const T&); diff --git a/include/spdlog/sinks/android_sink.h b/include/spdlog/sinks/android_sink.h index d38133d6..be2d3ad8 100644 --- a/include/spdlog/sinks/android_sink.h +++ b/include/spdlog/sinks/android_sink.h @@ -31,7 +31,7 @@ namespace sinks class android_sink : public sink { public: - explicit android_sink(const std::string& tag = "spdlog", bool use_raw_msg = false): _tag(tag), _use_raw_msg(use_raw_msg){} + explicit android_sink(const std::string& tag = "spdlog", bool use_raw_msg = false): _tag(tag), _use_raw_msg(use_raw_msg) {} void log(const details::log_msg& msg) override { diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index 33d02445..0e5e53c6 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -14,112 +14,114 @@ 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 SPDLOG_FINAL: 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 color_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: - bool is_color_terminal_; - sink_ptr sink_; - std::map colors_; - }; - - inline ansicolor_sink::ansicolor_sink(sink_ptr wrapped_sink): sink_(wrapped_sink) - { - is_color_terminal_ = details::os::is_color_terminal(); - colors_[level::trace] = cyan; - colors_[level::debug] = cyan; - colors_[level::info] = bold; - colors_[level::warn] = yellow + bold; - colors_[level::err] = red + bold; - colors_[level::critical] = bold + on_red; - colors_[level::off] = reset; - } - - inline void ansicolor_sink::log(const details::log_msg& msg) - { - // Wrap the originally formatted message in color codes. - // If color is not supported in the terminal, log as is instead. - if (is_color_terminal_) { - const std::string& prefix = colors_[msg.level]; - const std::string& s = msg.formatted.str(); - const std::string& suffix = reset; - details::log_msg m; - m.level = msg.level; - m.logger_name = msg.logger_name; - m.time = msg.time; - m.thread_id = msg.thread_id; - m.formatted << prefix << s << suffix; - sink_->log(m); - } - else { - sink_->log(msg); - } - } - - inline void ansicolor_sink::flush() - { - sink_->flush(); - } - - inline void ansicolor_sink::set_color(level::level_enum color_level, const std::string& color) - { - colors_[color_level] = color; - } - - inline ansicolor_sink::~ansicolor_sink() - { - flush(); - } - - } // namespace sinks +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 SPDLOG_FINAL: 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 color_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: + bool is_color_terminal_; + sink_ptr sink_; + std::map colors_; +}; + +inline ansicolor_sink::ansicolor_sink(sink_ptr wrapped_sink): sink_(wrapped_sink) +{ + is_color_terminal_ = details::os::is_color_terminal(); + colors_[level::trace] = cyan; + colors_[level::debug] = cyan; + colors_[level::info] = bold; + colors_[level::warn] = yellow + bold; + colors_[level::err] = red + bold; + colors_[level::critical] = bold + on_red; + colors_[level::off] = reset; +} + +inline void ansicolor_sink::log(const details::log_msg& msg) +{ + // Wrap the originally formatted message in color codes. + // If color is not supported in the terminal, log as is instead. + if (is_color_terminal_) + { + const std::string& prefix = colors_[msg.level]; + const std::string& s = msg.formatted.str(); + const std::string& suffix = reset; + details::log_msg m; + m.level = msg.level; + m.logger_name = msg.logger_name; + m.time = msg.time; + m.thread_id = msg.thread_id; + m.formatted << prefix << s << suffix; + sink_->log(m); + } + else + { + sink_->log(msg); + } +} + +inline void ansicolor_sink::flush() +{ + sink_->flush(); +} + +inline void ansicolor_sink::set_color(level::level_enum color_level, const std::string& color) +{ + colors_[color_level] = color; +} + +inline ansicolor_sink::~ansicolor_sink() +{ + flush(); +} + +} // namespace sinks } // namespace spdlog From def86e6e204da0aa19931a2d39fadddf1614a9f7 Mon Sep 17 00:00:00 2001 From: gabime Date: Wed, 17 May 2017 00:17:46 +0300 Subject: [PATCH 32/33] Fixed forgotten inline keyword --- include/spdlog/details/os.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 83700666..f96dc60d 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -422,7 +422,7 @@ inline int pid() // Detrmine if the terminal supports colors // Source: https://github.com/agauniyal/rang/ -bool is_color_terminal() +inline bool is_color_terminal() { #ifdef _WIN32 return true; From c6c5a46560d5398b764419c7dcdb56eac5b8dc53 Mon Sep 17 00:00:00 2001 From: Elias Kosunen Date: Wed, 17 May 2017 21:07:20 +0300 Subject: [PATCH 33/33] Fix OSX builds of details/os.h --- include/spdlog/details/os.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index f96dc60d..91163efa 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -13,8 +13,8 @@ #include #include #include -#include -#include +#include +#include #include #include