From ee6f165a1fbb7ae6820c84ace7d2fe22851c6c73 Mon Sep 17 00:00:00 2001 From: gabime Date: Tue, 25 Jun 2019 17:55:20 +0300 Subject: [PATCH 01/12] New duplicate filter sink --- include/spdlog/sinks/dup_filter_sink.h | 89 ++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 include/spdlog/sinks/dup_filter_sink.h diff --git a/include/spdlog/sinks/dup_filter_sink.h b/include/spdlog/sinks/dup_filter_sink.h new file mode 100644 index 00000000..309c639e --- /dev/null +++ b/include/spdlog/sinks/dup_filter_sink.h @@ -0,0 +1,89 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +#include "dist_sink.h" +#include "spdlog/details/null_mutex.h" +#include "spdlog/details/log_msg.h" + +#include +#include + +// Duplicate remove sink. +// Filter the message if previous one is identical and less than max max_skip_duration have passed +// +// Example: +// auto d = std::make_shared(std::chrono::seconds(5)); +// d->add_sink(std::make_shared()); +// spdlog::logger l("logger", d); +// l.info("Hello"); +// l.info("Hello"); +// l.info("Hello"); +// l.info("Different Hello"); +// +// Will produce: +// [2019-06-25 17:50:56.511] [logger] [info] Hello +// [2019-06-25 17:50:56.512] [logger] [info] 3 duplicate messages.. +// [2019-06-25 17:50:56.512] [logger] [info] Different Hello + + + +namespace spdlog { +namespace sinks { +template +class dup_filter_sink : public dist_sink +{ +public: + template + explicit dup_filter_sink(std::chrono::duration max_ignore_duration) + : max_skip_duration_{max_ignore_duration} + , last_msg_time_{log_clock::now()} + , skip_counter_{0} + {} + +protected: + std::chrono::microseconds max_skip_duration_; + log_clock::time_point last_msg_time_; + size_t skip_counter_; + std::string last_msg_payload_; + + void sink_it_(const details::log_msg &msg) override + { + auto msg_time = msg.time; + auto delta_time = msg_time - last_msg_time_; + last_msg_time_ = msg_time; + + if (delta_time < max_skip_duration_ && last_msg_payload_ == msg.payload) + { + skip_counter_++; + return; + } + + // got different message from the previous + if (skip_counter_ > 0) + { + fmt::basic_memory_buffer buf; + fmt::format_to(buf, "{} duplicate messages..", skip_counter_); + details::log_msg skipped_msg{msg.logger_name, msg.level, string_view_t{buf.data(), buf.size()}}; + + // log the skip notification + for (auto &sink : dist_sink::sinks_) + { + if (sink->should_log(msg.level)) + { + sink->log(skipped_msg); + } + } + skip_counter_ = 0; + } + + last_msg_payload_.assign(msg.payload.data(), msg.payload.data() + msg.payload.size()); + dist_sink::sink_it_(msg); + } +}; + +using dup_filter_sink_mt = dup_filter_sink; +using dup_filter_sink_st = dup_filter_sink; +} // namespace sinks +} // namespace spdlog From 5dd260c336287ffa144b4585fdc28ef9c34206b2 Mon Sep 17 00:00:00 2001 From: gabime Date: Tue, 25 Jun 2019 17:56:25 +0300 Subject: [PATCH 02/12] Added missing include to dist_sink --- include/spdlog/sinks/dist_sink.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/spdlog/sinks/dist_sink.h b/include/spdlog/sinks/dist_sink.h index 45ffa143..c7f207d7 100644 --- a/include/spdlog/sinks/dist_sink.h +++ b/include/spdlog/sinks/dist_sink.h @@ -6,6 +6,7 @@ #include "base_sink.h" #include "spdlog/details/log_msg.h" #include "spdlog/details/null_mutex.h" +#include "spdlog/details/pattern_formatter.h" #include #include @@ -47,7 +48,6 @@ public: protected: void sink_it_(const details::log_msg &msg) override { - for (auto &sink : sinks_) { if (sink->should_log(msg.level)) From 7f3b5fb84dc1fae3b03fd3ae2d1b06835752823a Mon Sep 17 00:00:00 2001 From: gabime Date: Thu, 27 Jun 2019 17:17:25 +0300 Subject: [PATCH 03/12] Fix dup filter --- include/spdlog/sinks/dup_filter_sink.h | 75 +++++++++++++------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/include/spdlog/sinks/dup_filter_sink.h b/include/spdlog/sinks/dup_filter_sink.h index 309c639e..67a171ef 100644 --- a/include/spdlog/sinks/dup_filter_sink.h +++ b/include/spdlog/sinks/dup_filter_sink.h @@ -7,24 +7,30 @@ #include "spdlog/details/null_mutex.h" #include "spdlog/details/log_msg.h" +#include #include #include -// Duplicate remove sink. -// Filter the message if previous one is identical and less than max max_skip_duration have passed +// Duplicate message removal sink. +// Skip the message if previous one is identical and less than "max_skip_duration" have passed // // Example: -// auto d = std::make_shared(std::chrono::seconds(5)); -// d->add_sink(std::make_shared()); -// spdlog::logger l("logger", d); -// l.info("Hello"); -// l.info("Hello"); -// l.info("Hello"); -// l.info("Different Hello"); +// +// #include "spdlog/sinks/dup_filter_sink.h" +// +// int main() { +// auto dup_filter = std::make_shared(std::chrono::seconds(5)); +// dup_filter->add_sink(std::make_shared()); +// spdlog::logger l("logger", dup_filter); +// l.info("Hello"); +// l.info("Hello"); +// l.info("Hello"); +// l.info("Different Hello"); +// } // // Will produce: // [2019-06-25 17:50:56.511] [logger] [info] Hello -// [2019-06-25 17:50:56.512] [logger] [info] 3 duplicate messages.. +// [2019-06-25 17:50:56.512] [logger] [info] Skipped 3 duplicate messages.. // [2019-06-25 17:50:56.512] [logger] [info] Different Hello @@ -36,54 +42,51 @@ class dup_filter_sink : public dist_sink { public: template - explicit dup_filter_sink(std::chrono::duration max_ignore_duration) - : max_skip_duration_{max_ignore_duration} - , last_msg_time_{log_clock::now()} - , skip_counter_{0} + explicit dup_filter_sink(std::chrono::duration max_skip_duration) + : max_skip_duration_{max_skip_duration} {} protected: std::chrono::microseconds max_skip_duration_; log_clock::time_point last_msg_time_; - size_t skip_counter_; std::string last_msg_payload_; + size_t skip_counter_ = 0; void sink_it_(const details::log_msg &msg) override { - auto msg_time = msg.time; - auto delta_time = msg_time - last_msg_time_; - last_msg_time_ = msg_time; - - if (delta_time < max_skip_duration_ && last_msg_payload_ == msg.payload) + bool filtered = filter_(msg); + if(!filtered) { - skip_counter_++; + skip_counter_ += 1; return; } - // got different message from the previous - if (skip_counter_ > 0) + // log the "skipped.." message + if(skip_counter_ > 0) { - fmt::basic_memory_buffer buf; - fmt::format_to(buf, "{} duplicate messages..", skip_counter_); + fmt::basic_memory_buffer buf; + fmt::format_to(buf, "Skipped {} duplicate messages..", skip_counter_); details::log_msg skipped_msg{msg.logger_name, msg.level, string_view_t{buf.data(), buf.size()}}; - - // log the skip notification - for (auto &sink : dist_sink::sinks_) - { - if (sink->should_log(msg.level)) - { - sink->log(skipped_msg); - } - } - skip_counter_ = 0; + dist_sink::sink_it_(skipped_msg); } - last_msg_payload_.assign(msg.payload.data(), msg.payload.data() + msg.payload.size()); + // log current message dist_sink::sink_it_(msg); + last_msg_time_= msg.time; + skip_counter_ = 0; + last_msg_payload_.assign(msg.payload.data(), msg.payload.data() + msg.payload.size()); + } + + // return whether the log msg should be displayed (true) or skipped (false) + bool filter_(const details::log_msg &msg) + { + auto filter_duration = msg.time - last_msg_time_; + return (filter_duration > max_skip_duration_) || (msg.payload != last_msg_payload_); } }; using dup_filter_sink_mt = dup_filter_sink; using dup_filter_sink_st = dup_filter_sink; + } // namespace sinks } // namespace spdlog From 98e151fda75edb814dadbfed7df3fdad70f060d8 Mon Sep 17 00:00:00 2001 From: gabime Date: Thu, 27 Jun 2019 17:40:40 +0300 Subject: [PATCH 04/12] Added tests for dup_filter sink --- tests/CMakeLists.txt | 3 +- tests/test_dup_filter.cpp | 77 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 tests/test_dup_filter.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9bde839c..3f07ede8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -14,7 +14,8 @@ set(SPDLOG_UTESTS_SOURCES test_mpmc_q.cpp test_sink.h test_fmt_helper.cpp - test_stdout_api.cpp) + test_stdout_api.cpp + test_dup_filter.cpp) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs") enable_testing() diff --git a/tests/test_dup_filter.cpp b/tests/test_dup_filter.cpp new file mode 100644 index 00000000..8ee9d832 --- /dev/null +++ b/tests/test_dup_filter.cpp @@ -0,0 +1,77 @@ +#include "includes.h" +#include "spdlog/sinks/dup_filter_sink.h" +#include "test_sink.h" + +using namespace spdlog; +using namespace spdlog::sinks; + + +TEST_CASE("dup_filter_test1", "[dup_filter_sink]") +{ + dup_filter_sink_st dup_sink {std::chrono::seconds{5}}; + auto test_sink = std::make_shared(); + dup_sink.add_sink(test_sink); + + for(int i = 0; i < 10; i++) + { + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + } + + REQUIRE(test_sink->msg_counter() == 1); +} + +TEST_CASE("dup_filter_test2", "[dup_filter_sink]") +{ + dup_filter_sink_st dup_sink {std::chrono::seconds{0}}; + auto test_sink = std::make_shared(); + dup_sink.add_sink(test_sink); + + for(int i = 0; i < 10; i++) + { + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + } + + REQUIRE(test_sink->msg_counter() == 10); +} + +TEST_CASE("dup_filter_test3", "[dup_filter_sink]") +{ + dup_filter_sink_st dup_sink {std::chrono::seconds{0}}; + auto test_sink = std::make_shared(); + dup_sink.add_sink(test_sink); + + for(int i = 0; i < 10; i++) + { + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"}); + } + + REQUIRE(test_sink->msg_counter() == 20); +} + +TEST_CASE("dup_filter_test4", "[dup_filter_sink]") +{ + dup_filter_sink_st dup_sink {std::chrono::milliseconds{10}}; + auto test_sink = std::make_shared(); + dup_sink.add_sink(test_sink); + + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message"}); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message"}); + REQUIRE(test_sink->msg_counter() == 2); +} + +TEST_CASE("dup_filter_test5", "[dup_filter_sink]") +{ + dup_filter_sink_st dup_sink {std::chrono::seconds{5}}; + auto test_sink = std::make_shared(); + dup_sink.add_sink(test_sink); + + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"}); + + REQUIRE(test_sink->msg_counter() == 3); // skip 2 messages but log the "skipped.." message before message2 +} + From b279196af26509ee019a7032919763ff13c50e3f Mon Sep 17 00:00:00 2001 From: gabime Date: Thu, 27 Jun 2019 17:41:04 +0300 Subject: [PATCH 05/12] Added tests for dup_filter sink --- tests/test_dup_filter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_dup_filter.cpp b/tests/test_dup_filter.cpp index 8ee9d832..4f5a53f3 100644 --- a/tests/test_dup_filter.cpp +++ b/tests/test_dup_filter.cpp @@ -51,7 +51,7 @@ TEST_CASE("dup_filter_test3", "[dup_filter_sink]") TEST_CASE("dup_filter_test4", "[dup_filter_sink]") { - dup_filter_sink_st dup_sink {std::chrono::milliseconds{10}}; + dup_filter_sink_mt dup_sink {std::chrono::milliseconds{10}}; auto test_sink = std::make_shared(); dup_sink.add_sink(test_sink); @@ -63,7 +63,7 @@ TEST_CASE("dup_filter_test4", "[dup_filter_sink]") TEST_CASE("dup_filter_test5", "[dup_filter_sink]") { - dup_filter_sink_st dup_sink {std::chrono::seconds{5}}; + dup_filter_sink_mt dup_sink {std::chrono::seconds{5}}; auto test_sink = std::make_shared(); dup_sink.add_sink(test_sink); From 29f2eeea3190d27408ad7305bf643dfd30ae4903 Mon Sep 17 00:00:00 2001 From: gabime Date: Thu, 27 Jun 2019 23:56:37 +0300 Subject: [PATCH 06/12] Removed formatter_ member from the sink interface --- include/spdlog/sinks/ansicolor_sink-inl.h | 1 + include/spdlog/sinks/ansicolor_sink.h | 1 + include/spdlog/sinks/base_sink-inl.h | 12 ++++++++++++ include/spdlog/sinks/base_sink.h | 8 ++++++-- include/spdlog/sinks/basic_file_sink-inl.h | 2 +- include/spdlog/sinks/daily_file_sink.h | 2 +- include/spdlog/sinks/dup_filter_sink.h | 10 ++++------ include/spdlog/sinks/msvc_sink.h | 2 +- include/spdlog/sinks/ostream_sink.h | 2 +- include/spdlog/sinks/rotating_file_sink-inl.h | 2 +- include/spdlog/sinks/sink-inl.h | 10 +--------- include/spdlog/sinks/sink.h | 10 +--------- include/spdlog/sinks/stdout_sinks-inl.h | 1 + include/spdlog/sinks/stdout_sinks.h | 3 ++- include/spdlog/sinks/syslog_sink.h | 2 +- include/spdlog/sinks/wincolor_sink-inl.h | 5 ++++- include/spdlog/sinks/wincolor_sink.h | 3 ++- tests/test_dup_filter.cpp | 18 ++++++++---------- 18 files changed, 49 insertions(+), 45 deletions(-) diff --git a/include/spdlog/sinks/ansicolor_sink-inl.h b/include/spdlog/sinks/ansicolor_sink-inl.h index b5f6aff9..74b9c3ec 100644 --- a/include/spdlog/sinks/ansicolor_sink-inl.h +++ b/include/spdlog/sinks/ansicolor_sink-inl.h @@ -16,6 +16,7 @@ template SPDLOG_INLINE ansicolor_sink::ansicolor_sink(FILE *target_file, color_mode mode) : target_file_(target_file) , mutex_(ConsoleMutex::mutex()) + , formatter_(details::make_unique()) { set_color_mode(mode); diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index e1d5f7e4..f383b5a5 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -79,6 +79,7 @@ private: FILE *target_file_; mutex_t &mutex_; bool should_do_colors_; + std::unique_ptr formatter_; std::unordered_map colors_; void print_ccode_(const string_view_t &color_code); void print_range_(const fmt::memory_buffer &formatted, size_t start, size_t end); diff --git a/include/spdlog/sinks/base_sink-inl.h b/include/spdlog/sinks/base_sink-inl.h index 553f2515..565cdc17 100644 --- a/include/spdlog/sinks/base_sink-inl.h +++ b/include/spdlog/sinks/base_sink-inl.h @@ -10,6 +10,18 @@ #include "spdlog/common.h" #include "spdlog/details/pattern_formatter.h" +#include + +template +SPDLOG_INLINE spdlog::sinks::base_sink::base_sink() + : formatter_{details::make_unique()} +{} + +template +SPDLOG_INLINE spdlog::sinks::base_sink::base_sink(std::unique_ptr formatter) + : formatter_{std::move(formatter)} +{} + template void SPDLOG_INLINE spdlog::sinks::base_sink::log(const details::log_msg &msg) { diff --git a/include/spdlog/sinks/base_sink.h b/include/spdlog/sinks/base_sink.h index 63010afa..4ca51c75 100644 --- a/include/spdlog/sinks/base_sink.h +++ b/include/spdlog/sinks/base_sink.h @@ -19,7 +19,8 @@ template class base_sink : public sink { public: - base_sink() = default; + base_sink(); + explicit base_sink(std::unique_ptr formatter); base_sink(const base_sink &) = delete; base_sink &operator=(const base_sink &) = delete; void log(const details::log_msg &msg) final; @@ -28,11 +29,14 @@ public: void set_formatter(std::unique_ptr sink_formatter) final; protected: + // sink formatter + std::unique_ptr formatter_; + Mutex mutex_; + virtual void sink_it_(const details::log_msg &msg) = 0; virtual void flush_() = 0; virtual void set_pattern_(const std::string &pattern); virtual void set_formatter_(std::unique_ptr sink_formatter); - Mutex mutex_; }; } // namespace sinks } // namespace spdlog diff --git a/include/spdlog/sinks/basic_file_sink-inl.h b/include/spdlog/sinks/basic_file_sink-inl.h index 6683eeba..108b8ff7 100644 --- a/include/spdlog/sinks/basic_file_sink-inl.h +++ b/include/spdlog/sinks/basic_file_sink-inl.h @@ -29,7 +29,7 @@ template SPDLOG_INLINE void basic_file_sink::sink_it_(const details::log_msg &msg) { fmt::memory_buffer formatted; - sink::formatter_->format(msg, formatted); + base_sink::formatter_->format(msg, formatted); file_helper_.write(formatted); } diff --git a/include/spdlog/sinks/daily_file_sink.h b/include/spdlog/sinks/daily_file_sink.h index 8c907171..687da043 100644 --- a/include/spdlog/sinks/daily_file_sink.h +++ b/include/spdlog/sinks/daily_file_sink.h @@ -74,7 +74,7 @@ protected: rotation_tp_ = next_rotation_tp_(); } fmt::memory_buffer formatted; - sink::formatter_->format(msg, formatted); + base_sink::formatter_->format(msg, formatted); file_helper_.write(formatted); } diff --git a/include/spdlog/sinks/dup_filter_sink.h b/include/spdlog/sinks/dup_filter_sink.h index 67a171ef..a244b4e9 100644 --- a/include/spdlog/sinks/dup_filter_sink.h +++ b/include/spdlog/sinks/dup_filter_sink.h @@ -33,8 +33,6 @@ // [2019-06-25 17:50:56.512] [logger] [info] Skipped 3 duplicate messages.. // [2019-06-25 17:50:56.512] [logger] [info] Different Hello - - namespace spdlog { namespace sinks { template @@ -55,14 +53,14 @@ protected: void sink_it_(const details::log_msg &msg) override { bool filtered = filter_(msg); - if(!filtered) + if (!filtered) { skip_counter_ += 1; return; } // log the "skipped.." message - if(skip_counter_ > 0) + if (skip_counter_ > 0) { fmt::basic_memory_buffer buf; fmt::format_to(buf, "Skipped {} duplicate messages..", skip_counter_); @@ -72,7 +70,7 @@ protected: // log current message dist_sink::sink_it_(msg); - last_msg_time_= msg.time; + last_msg_time_ = msg.time; skip_counter_ = 0; last_msg_payload_.assign(msg.payload.data(), msg.payload.data() + msg.payload.size()); } @@ -81,7 +79,7 @@ protected: bool filter_(const details::log_msg &msg) { auto filter_duration = msg.time - last_msg_time_; - return (filter_duration > max_skip_duration_) || (msg.payload != last_msg_payload_); + return (filter_duration > max_skip_duration_) || (msg.payload != last_msg_payload_); } }; diff --git a/include/spdlog/sinks/msvc_sink.h b/include/spdlog/sinks/msvc_sink.h index e2c8fa34..08e029a0 100644 --- a/include/spdlog/sinks/msvc_sink.h +++ b/include/spdlog/sinks/msvc_sink.h @@ -29,7 +29,7 @@ protected: { fmt::memory_buffer formatted; - sink::formatter_->format(msg, formatted); + base_sink::formatter_->format(msg, formatted); OutputDebugStringA(fmt::to_string(formatted).c_str()); } diff --git a/include/spdlog/sinks/ostream_sink.h b/include/spdlog/sinks/ostream_sink.h index a2a5a3a3..6a728a3a 100644 --- a/include/spdlog/sinks/ostream_sink.h +++ b/include/spdlog/sinks/ostream_sink.h @@ -26,7 +26,7 @@ protected: void sink_it_(const details::log_msg &msg) override { fmt::memory_buffer formatted; - sink::formatter_->format(msg, formatted); + base_sink::formatter_->format(msg, formatted); ostream_.write(formatted.data(), static_cast(formatted.size())); if (force_flush_) { diff --git a/include/spdlog/sinks/rotating_file_sink-inl.h b/include/spdlog/sinks/rotating_file_sink-inl.h index 588619f8..c5d7c3a2 100644 --- a/include/spdlog/sinks/rotating_file_sink-inl.h +++ b/include/spdlog/sinks/rotating_file_sink-inl.h @@ -67,7 +67,7 @@ template SPDLOG_INLINE void rotating_file_sink::sink_it_(const details::log_msg &msg) { fmt::memory_buffer formatted; - sink::formatter_->format(msg, formatted); + base_sink::formatter_->format(msg, formatted); current_size_ += formatted.size(); if (current_size_ > max_size_) { diff --git a/include/spdlog/sinks/sink-inl.h b/include/spdlog/sinks/sink-inl.h index 11b77fc9..b5f43488 100644 --- a/include/spdlog/sinks/sink-inl.h +++ b/include/spdlog/sinks/sink-inl.h @@ -10,14 +10,6 @@ #include "spdlog/common.h" #include "spdlog/details/pattern_formatter.h" -SPDLOG_INLINE spdlog::sinks::sink::sink() - : formatter_{details::make_unique()} -{} - -SPDLOG_INLINE spdlog::sinks::sink::sink(std::unique_ptr formatter) - : formatter_{std::move(formatter)} -{} - SPDLOG_INLINE bool spdlog::sinks::sink::should_log(spdlog::level::level_enum msg_level) const { return msg_level >= level_.load(std::memory_order_relaxed); @@ -25,7 +17,7 @@ SPDLOG_INLINE bool spdlog::sinks::sink::should_log(spdlog::level::level_enum msg SPDLOG_INLINE void spdlog::sinks::sink::set_level(level::level_enum log_level) { - level_.store(log_level); + level_.store(log_level, std::memory_order_relaxed); } SPDLOG_INLINE spdlog::level::level_enum spdlog::sinks::sink::level() const diff --git a/include/spdlog/sinks/sink.h b/include/spdlog/sinks/sink.h index f9703fdf..6515f1f1 100644 --- a/include/spdlog/sinks/sink.h +++ b/include/spdlog/sinks/sink.h @@ -12,27 +12,19 @@ namespace sinks { class sink { public: - sink(); - - explicit sink(std::unique_ptr formatter); virtual ~sink() = default; virtual void log(const details::log_msg &msg) = 0; virtual void flush() = 0; virtual void set_pattern(const std::string &pattern) = 0; virtual void set_formatter(std::unique_ptr sink_formatter) = 0; - bool should_log(level::level_enum msg_level) const; - void set_level(level::level_enum log_level); - level::level_enum level() const; + bool should_log(level::level_enum msg_level) const; protected: // sink log level - default is all level_t level_{level::trace}; - - // sink formatter - std::unique_ptr formatter_; }; } // namespace sinks diff --git a/include/spdlog/sinks/stdout_sinks-inl.h b/include/spdlog/sinks/stdout_sinks-inl.h index 37a2f5f2..3c55ce66 100644 --- a/include/spdlog/sinks/stdout_sinks-inl.h +++ b/include/spdlog/sinks/stdout_sinks-inl.h @@ -18,6 +18,7 @@ template SPDLOG_INLINE stdout_sink_base::stdout_sink_base(FILE *file) : mutex_(ConsoleMutex::mutex()) , file_(file) + , formatter_(details::make_unique()) {} template diff --git a/include/spdlog/sinks/stdout_sinks.h b/include/spdlog/sinks/stdout_sinks.h index c0852383..04d2fa42 100644 --- a/include/spdlog/sinks/stdout_sinks.h +++ b/include/spdlog/sinks/stdout_sinks.h @@ -28,9 +28,10 @@ public: void set_formatter(std::unique_ptr sink_formatter) override; -private: +protected: mutex_t &mutex_; FILE *file_; + std::unique_ptr formatter_; }; template diff --git a/include/spdlog/sinks/syslog_sink.h b/include/spdlog/sinks/syslog_sink.h index 42dbda0f..f58da3e2 100644 --- a/include/spdlog/sinks/syslog_sink.h +++ b/include/spdlog/sinks/syslog_sink.h @@ -52,7 +52,7 @@ protected: if (enable_formatting_) { fmt::memory_buffer formatted; - sink::formatter_->format(msg, formatted); + base_sink::formatter_->format(msg, formatted); payload = string_view_t(formatted.data(), formatted.size()); } else diff --git a/include/spdlog/sinks/wincolor_sink-inl.h b/include/spdlog/sinks/wincolor_sink-inl.h index 12c772cc..ff99836d 100644 --- a/include/spdlog/sinks/wincolor_sink-inl.h +++ b/include/spdlog/sinks/wincolor_sink-inl.h @@ -8,14 +8,17 @@ #endif #include "spdlog/common.h" +#include "spdlog/details/pattern_formatter.h" namespace spdlog { namespace sinks { template SPDLOG_INLINE wincolor_sink::wincolor_sink(HANDLE out_handle, color_mode mode) - : out_handle_(out_handle) + : + , out_handle_(out_handle) , mutex_(ConsoleMutex::mutex()) + , formatter_(details::make_unique()) { set_color_mode(mode); colors_[level::trace] = WHITE; diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h index 94a84912..5a969704 100644 --- a/include/spdlog/sinks/wincolor_sink.h +++ b/include/spdlog/sinks/wincolor_sink.h @@ -45,11 +45,12 @@ public: void set_formatter(std::unique_ptr sink_formatter) override final; void set_color_mode(color_mode mode); -private: +protected: using mutex_t = typename ConsoleMutex::mutex_t; HANDLE out_handle_; mutex_t &mutex_; bool should_do_colors_; + std::unique_ptr formatter_; std::unordered_map colors_; // set color and return the orig console attributes (for resetting later) diff --git a/tests/test_dup_filter.cpp b/tests/test_dup_filter.cpp index 4f5a53f3..f6b6c476 100644 --- a/tests/test_dup_filter.cpp +++ b/tests/test_dup_filter.cpp @@ -5,14 +5,13 @@ using namespace spdlog; using namespace spdlog::sinks; - TEST_CASE("dup_filter_test1", "[dup_filter_sink]") { - dup_filter_sink_st dup_sink {std::chrono::seconds{5}}; + dup_filter_sink_st dup_sink{std::chrono::seconds{5}}; auto test_sink = std::make_shared(); dup_sink.add_sink(test_sink); - for(int i = 0; i < 10; i++) + for (int i = 0; i < 10; i++) { dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); } @@ -22,11 +21,11 @@ TEST_CASE("dup_filter_test1", "[dup_filter_sink]") TEST_CASE("dup_filter_test2", "[dup_filter_sink]") { - dup_filter_sink_st dup_sink {std::chrono::seconds{0}}; + dup_filter_sink_st dup_sink{std::chrono::seconds{0}}; auto test_sink = std::make_shared(); dup_sink.add_sink(test_sink); - for(int i = 0; i < 10; i++) + for (int i = 0; i < 10; i++) { dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); } @@ -36,11 +35,11 @@ TEST_CASE("dup_filter_test2", "[dup_filter_sink]") TEST_CASE("dup_filter_test3", "[dup_filter_sink]") { - dup_filter_sink_st dup_sink {std::chrono::seconds{0}}; + dup_filter_sink_st dup_sink{std::chrono::seconds{0}}; auto test_sink = std::make_shared(); dup_sink.add_sink(test_sink); - for(int i = 0; i < 10; i++) + for (int i = 0; i < 10; i++) { dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"}); @@ -51,7 +50,7 @@ TEST_CASE("dup_filter_test3", "[dup_filter_sink]") TEST_CASE("dup_filter_test4", "[dup_filter_sink]") { - dup_filter_sink_mt dup_sink {std::chrono::milliseconds{10}}; + dup_filter_sink_mt dup_sink{std::chrono::milliseconds{10}}; auto test_sink = std::make_shared(); dup_sink.add_sink(test_sink); @@ -63,7 +62,7 @@ TEST_CASE("dup_filter_test4", "[dup_filter_sink]") TEST_CASE("dup_filter_test5", "[dup_filter_sink]") { - dup_filter_sink_mt dup_sink {std::chrono::seconds{5}}; + dup_filter_sink_mt dup_sink{std::chrono::seconds{5}}; auto test_sink = std::make_shared(); dup_sink.add_sink(test_sink); @@ -74,4 +73,3 @@ TEST_CASE("dup_filter_test5", "[dup_filter_sink]") REQUIRE(test_sink->msg_counter() == 3); // skip 2 messages but log the "skipped.." message before message2 } - From 2ebc96d8eb691d9b8394e5fbdc3efcfc105a1f45 Mon Sep 17 00:00:00 2001 From: gabime Date: Fri, 28 Jun 2019 00:05:06 +0300 Subject: [PATCH 07/12] Fixed windows build --- include/spdlog/sinks/wincolor_sink-inl.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/spdlog/sinks/wincolor_sink-inl.h b/include/spdlog/sinks/wincolor_sink-inl.h index ff99836d..47216ba4 100644 --- a/include/spdlog/sinks/wincolor_sink-inl.h +++ b/include/spdlog/sinks/wincolor_sink-inl.h @@ -15,8 +15,7 @@ namespace sinks { template SPDLOG_INLINE wincolor_sink::wincolor_sink(HANDLE out_handle, color_mode mode) - : - , out_handle_(out_handle) + : out_handle_(out_handle) , mutex_(ConsoleMutex::mutex()) , formatter_(details::make_unique()) { From c75549f6dba202c3b3526df5a078a766ee8253c5 Mon Sep 17 00:00:00 2001 From: gabime Date: Fri, 28 Jun 2019 00:14:16 +0300 Subject: [PATCH 08/12] Removed un needed #include --- include/spdlog/sinks/sink-inl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/spdlog/sinks/sink-inl.h b/include/spdlog/sinks/sink-inl.h index b5f43488..d1da94a0 100644 --- a/include/spdlog/sinks/sink-inl.h +++ b/include/spdlog/sinks/sink-inl.h @@ -8,7 +8,6 @@ #endif #include "spdlog/common.h" -#include "spdlog/details/pattern_formatter.h" SPDLOG_INLINE bool spdlog::sinks::sink::should_log(spdlog::level::level_enum msg_level) const { From 71162ebdbb6e929571eba3c800ab2b806baa4b9f Mon Sep 17 00:00:00 2001 From: gabime Date: Fri, 28 Jun 2019 00:47:10 +0300 Subject: [PATCH 09/12] Fixed dup_filter test --- tests/test_dup_filter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_dup_filter.cpp b/tests/test_dup_filter.cpp index f6b6c476..3e2c68fa 100644 --- a/tests/test_dup_filter.cpp +++ b/tests/test_dup_filter.cpp @@ -28,6 +28,7 @@ TEST_CASE("dup_filter_test2", "[dup_filter_sink]") for (int i = 0; i < 10; i++) { dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); } REQUIRE(test_sink->msg_counter() == 10); From f03eaaaf33c0b82b0bc6ec56f0012cff6fc8ae16 Mon Sep 17 00:00:00 2001 From: gabime Date: Fri, 28 Jun 2019 00:48:30 +0300 Subject: [PATCH 10/12] Fixed dup_filter test --- tests/test_dup_filter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_dup_filter.cpp b/tests/test_dup_filter.cpp index 3e2c68fa..47541e0f 100644 --- a/tests/test_dup_filter.cpp +++ b/tests/test_dup_filter.cpp @@ -36,7 +36,7 @@ TEST_CASE("dup_filter_test2", "[dup_filter_sink]") TEST_CASE("dup_filter_test3", "[dup_filter_sink]") { - dup_filter_sink_st dup_sink{std::chrono::seconds{0}}; + dup_filter_sink_st dup_sink{std::chrono::seconds{1}}; auto test_sink = std::make_shared(); dup_sink.add_sink(test_sink); From 6e83abdbf2b86b4876aa72f5a770ccad2de98d7a Mon Sep 17 00:00:00 2001 From: gabime Date: Fri, 28 Jun 2019 01:01:22 +0300 Subject: [PATCH 11/12] Removed stdout_sinks from spdlog.cpp for faster library compile time --- include/spdlog/sinks/stdout_sinks-inl.h | 4 ---- include/spdlog/sinks/stdout_sinks.h | 3 +-- src/spdlog.cpp | 24 ------------------------ 3 files changed, 1 insertion(+), 30 deletions(-) diff --git a/include/spdlog/sinks/stdout_sinks-inl.h b/include/spdlog/sinks/stdout_sinks-inl.h index 3c55ce66..e9fccd37 100644 --- a/include/spdlog/sinks/stdout_sinks-inl.h +++ b/include/spdlog/sinks/stdout_sinks-inl.h @@ -3,10 +3,6 @@ #pragma once -#ifndef SPDLOG_HEADER_ONLY -#include "spdlog/sinks/stdout_sinks.h" -#endif - #include "spdlog/details/console_globals.h" #include diff --git a/include/spdlog/sinks/stdout_sinks.h b/include/spdlog/sinks/stdout_sinks.h index 04d2fa42..18971107 100644 --- a/include/spdlog/sinks/stdout_sinks.h +++ b/include/spdlog/sinks/stdout_sinks.h @@ -71,6 +71,5 @@ std::shared_ptr stderr_logger_st(const std::string &logger_name); } // namespace spdlog -#ifdef SPDLOG_HEADER_ONLY #include "stdout_sinks-inl.h" -#endif + diff --git a/src/spdlog.cpp b/src/spdlog.cpp index 63328d80..c41b4c33 100644 --- a/src/spdlog.cpp +++ b/src/spdlog.cpp @@ -80,30 +80,6 @@ template std::shared_ptr spdlog::stdout_color_st spdlog::stderr_color_mt(const std::string &logger_name, color_mode mode); template std::shared_ptr spdlog::stderr_color_st(const std::string &logger_name, color_mode mode); -// -// stdout/stderr sinks -// -#include "spdlog/sinks/stdout_sinks-inl.h" - -template class spdlog::sinks::stdout_sink_base; -template class spdlog::sinks::stdout_sink_base; - -template class spdlog::sinks::stdout_sink; -template class spdlog::sinks::stdout_sink; - -template class spdlog::sinks::stderr_sink; -template class spdlog::sinks::stderr_sink; - -// factory methods for stdout/stderr loggers -template std::shared_ptr spdlog::stdout_logger_mt(const std::string &logger_name); -template std::shared_ptr spdlog::stdout_logger_st(const std::string &logger_name); -template std::shared_ptr spdlog::stdout_logger_mt(const std::string &logger_name); -template std::shared_ptr spdlog::stdout_logger_st(const std::string &logger_name); - -template std::shared_ptr spdlog::stderr_logger_mt(const std::string &logger_name); -template std::shared_ptr spdlog::stderr_logger_st(const std::string &logger_name); -template std::shared_ptr spdlog::stderr_logger_mt(const std::string &logger_name); -template std::shared_ptr spdlog::stderr_logger_st(const std::string &logger_name); // Slightly modified version of fmt lib's format.cc source file. // Copyright (c) 2012 - 2016, Victor Zverovich From 94c2810b0a358f9bf52d2995b239b576ee6731ce Mon Sep 17 00:00:00 2001 From: gabime Date: Fri, 28 Jun 2019 01:41:11 +0300 Subject: [PATCH 12/12] Reduced max padding 128=>64 --- include/spdlog/details/pattern_formatter-inl.h | 6 ++---- tests/test_pattern_formatter.cpp | 8 +++----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/include/spdlog/details/pattern_formatter-inl.h b/include/spdlog/details/pattern_formatter-inl.h index fe92e7b9..14d93f08 100644 --- a/include/spdlog/details/pattern_formatter-inl.h +++ b/include/spdlog/details/pattern_formatter-inl.h @@ -84,9 +84,7 @@ private: const padding_info &padinfo_; fmt::memory_buffer &dest_; size_t total_pad_; - string_view_t spaces_{" " - " ", - 128}; + string_view_t spaces_{" ", 64}; }; class name_formatter : public flag_formatter @@ -1217,7 +1215,7 @@ SPDLOG_INLINE details::padding_info pattern_formatter::handle_padspec_(std::stri { using details::padding_info; using details::scoped_pad; - const size_t max_width = 128; + const size_t max_width = 64; if (it == end) { return padding_info{}; diff --git a/tests/test_pattern_formatter.cpp b/tests/test_pattern_formatter.cpp index f9d23d2a..094554e7 100644 --- a/tests/test_pattern_formatter.cpp +++ b/tests/test_pattern_formatter.cpp @@ -183,16 +183,14 @@ TEST_CASE("left_padded_huge", "[pattern_formatter]") { REQUIRE( log_to_str("Some message", "[%-300n] %v", spdlog::pattern_time_type::local, "\n") == - "[pattern_tester ]" - " Some message\n"); + "[pattern_tester ] Some message\n"); } TEST_CASE("left_padded_max", "[pattern_formatter]") { REQUIRE( - log_to_str("Some message", "[%-128n] %v", spdlog::pattern_time_type::local, "\n") == - "[pattern_tester ]" - " Some message\n"); + log_to_str("Some message", "[%-64n] %v", spdlog::pattern_time_type::local, "\n") == + "[pattern_tester ] Some message\n"); } TEST_CASE("clone-default-formatter", "[pattern_formatter]")