From 45e3e7041d2a2ee1d5e275666b7865e98a6190de Mon Sep 17 00:00:00 2001 From: Amir Cohen Date: Tue, 25 Apr 2017 19:30:11 +0300 Subject: [PATCH 1/7] 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 2/7] 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 3/7] 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 4/7] 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 5/7] 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 6/7] 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 7/7] 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