From f0cd9d15308007aa84068d0373b52bcaa67e3823 Mon Sep 17 00:00:00 2001 From: zydxhs Date: Fri, 2 Dec 2022 15:51:34 +0800 Subject: [PATCH 1/8] dup_filter_sink adds parameters to enable setting the level of skipped logs (#2563) * dup_filter_sink adds parameters to enable setting the level of skipped logs * rename the param name 'level' to 'notification_level' Co-authored-by: zhuyadong --- include/spdlog/sinks/dup_filter_sink.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/spdlog/sinks/dup_filter_sink.h b/include/spdlog/sinks/dup_filter_sink.h index 1a4fb348..3c96549c 100644 --- a/include/spdlog/sinks/dup_filter_sink.h +++ b/include/spdlog/sinks/dup_filter_sink.h @@ -20,7 +20,7 @@ // #include // // int main() { -// auto dup_filter = std::make_shared(std::chrono::seconds(5)); +// auto dup_filter = std::make_shared(std::chrono::seconds(5), level::info); // dup_filter->add_sink(std::make_shared()); // spdlog::logger l("logger", dup_filter); // l.info("Hello"); @@ -41,8 +41,9 @@ class dup_filter_sink : public dist_sink { public: template - explicit dup_filter_sink(std::chrono::duration max_skip_duration) + explicit dup_filter_sink(std::chrono::duration max_skip_duration, level::level_enum notification_level = level::info) : max_skip_duration_{max_skip_duration} + , log_level_{notification_level} {} protected: @@ -50,6 +51,7 @@ protected: log_clock::time_point last_msg_time_; std::string last_msg_payload_; size_t skip_counter_ = 0; + level::level_enum log_level_; void sink_it_(const details::log_msg &msg) override { @@ -67,7 +69,7 @@ protected: auto msg_size = ::snprintf(buf, sizeof(buf), "Skipped %u duplicate messages..", static_cast(skip_counter_)); if (msg_size > 0 && static_cast(msg_size) < sizeof(buf)) { - details::log_msg skipped_msg{msg.source, msg.logger_name, level::info, string_view_t{buf, static_cast(msg_size)}}; + details::log_msg skipped_msg{msg.source, msg.logger_name, log_level_, string_view_t{buf, static_cast(msg_size)}}; dist_sink::sink_it_(skipped_msg); } } From 8512000f36c2ad9b1265bd78b11c0b34151d6be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gy=C3=B6rgy=20Katona?= Date: Fri, 9 Dec 2022 09:25:17 +0100 Subject: [PATCH 2/8] Unnecessary backtrace begin/end logs (#2568) * add empty getter function to tracer * add unit test to check empty tracer Co-authored-by: Gyorgy Katona --- include/spdlog/details/backtracer-inl.h | 6 ++++++ include/spdlog/details/backtracer.h | 1 + include/spdlog/logger-inl.h | 2 +- tests/test_backtrace.cpp | 13 +++++++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/spdlog/details/backtracer-inl.h b/include/spdlog/details/backtracer-inl.h index 2621c8f7..40eba408 100644 --- a/include/spdlog/details/backtracer-inl.h +++ b/include/spdlog/details/backtracer-inl.h @@ -54,6 +54,12 @@ SPDLOG_INLINE void backtracer::push_back(const log_msg &msg) messages_.push_back(log_msg_buffer{msg}); } +SPDLOG_INLINE bool backtracer::empty() const +{ + std::lock_guard lock{mutex_}; + return messages_.empty(); +} + // pop all items in the q and apply the given fun on each of them. SPDLOG_INLINE void backtracer::foreach_pop(std::function fun) { diff --git a/include/spdlog/details/backtracer.h b/include/spdlog/details/backtracer.h index b336ee77..13785d85 100644 --- a/include/spdlog/details/backtracer.h +++ b/include/spdlog/details/backtracer.h @@ -32,6 +32,7 @@ public: void disable(); bool enabled() const; void push_back(const log_msg &msg); + bool empty() const; // pop all items in the q and apply the given fun on each of them. void foreach_pop(std::function fun); diff --git a/include/spdlog/logger-inl.h b/include/spdlog/logger-inl.h index 411f2cb5..ff82db4c 100644 --- a/include/spdlog/logger-inl.h +++ b/include/spdlog/logger-inl.h @@ -210,7 +210,7 @@ SPDLOG_INLINE void logger::flush_() SPDLOG_INLINE void logger::dump_backtrace_() { using details::log_msg; - if (tracer_.enabled()) + if (tracer_.enabled() && !tracer_.empty()) { sink_it_(log_msg{name(), level::info, "****************** Backtrace Start ******************"}); tracer_.foreach_pop([this](const log_msg &msg) { this->sink_it_(msg); }); diff --git a/tests/test_backtrace.cpp b/tests/test_backtrace.cpp index 9504b82b..6cf9ec55 100644 --- a/tests/test_backtrace.cpp +++ b/tests/test_backtrace.cpp @@ -31,6 +31,19 @@ TEST_CASE("bactrace1", "[bactrace]") REQUIRE(test_sink->lines()[7] == "****************** Backtrace End ********************"); } +TEST_CASE("bactrace-empty", "[bactrace]") +{ + using spdlog::sinks::test_sink_st; + auto test_sink = std::make_shared(); + size_t backtrace_size = 5; + + spdlog::logger logger("test-backtrace", test_sink); + logger.set_pattern("%v"); + logger.enable_backtrace(backtrace_size); + logger.dump_backtrace(); + REQUIRE(test_sink->lines().size() == 0); +} + TEST_CASE("bactrace-async", "[bactrace]") { using spdlog::sinks::test_sink_mt; From dd0d0f68c4e331eaf65953d4f21579ccef7a0d87 Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Sat, 10 Dec 2022 00:25:31 +0200 Subject: [PATCH 3/8] Added compile mscv_sink.h to tests --- tests/includes.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/includes.h b/tests/includes.h index 16394440..100984cc 100644 --- a/tests/includes.h +++ b/tests/includes.h @@ -32,4 +32,5 @@ #include "spdlog/sinks/ostream_sink.h" #include "spdlog/sinks/rotating_file_sink.h" #include "spdlog/sinks/stdout_color_sinks.h" +#include "spdlog/sinks/msvc_sink.h" #include "spdlog/pattern_formatter.h" From ff88b13c356935acf8e51d3799aa1a065dde40a2 Mon Sep 17 00:00:00 2001 From: NaDDu Date: Sat, 10 Dec 2022 07:28:28 +0900 Subject: [PATCH 4/8] Fixed variable name (#2573) * fixed variable name * Changed the variable name from check_debbugger_present_ to check_debugger_present_. Co-authored-by: cpp --- include/spdlog/sinks/msvc_sink.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/spdlog/sinks/msvc_sink.h b/include/spdlog/sinks/msvc_sink.h index 09008b78..708b35ac 100644 --- a/include/spdlog/sinks/msvc_sink.h +++ b/include/spdlog/sinks/msvc_sink.h @@ -26,13 +26,13 @@ class msvc_sink : public base_sink { public: msvc_sink() = default; - msvc_sink(bool check_ebugger_present) - : check_debbugger_present_{check_ebugger_present} {}; + msvc_sink(bool check_debugger_present) + : check_debugger_present_{check_debugger_present} {}; protected: void sink_it_(const details::log_msg &msg) override { - if (check_debbugger_present_ && !IsDebuggerPresent()) + if (check_debugger_present_ && !IsDebuggerPresent()) { return; } @@ -44,7 +44,7 @@ protected: void flush_() override {} - bool check_debbugger_present_ = true; + bool check_debugger_present_ = true; }; using msvc_sink_mt = msvc_sink; From edc51df1bdad8667b628999394a1e7c4dc6f3658 Mon Sep 17 00:00:00 2001 From: Darby Payne Date: Sun, 11 Dec 2022 00:58:02 -0800 Subject: [PATCH 5/8] Feature/add system includes option (#2575) * Adding system includes option * Adding system includes option --- CMakeLists.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a66e8405..61d21781 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,7 @@ option(SPDLOG_SANITIZE_ADDRESS "Enable address sanitizer in tests" OFF) option(SPDLOG_BUILD_WARNINGS "Enable compiler warnings" OFF) # install options +option(SPDLOG_SYSTEM_INCLUDES "Include as system headers (skip for clang-tidy)." OFF) option(SPDLOG_INSTALL "Generate the install target" ${SPDLOG_MASTER_PROJECT}) option(SPDLOG_USE_STD_FORMAT "Use std::format instead of fmt library." OFF) option(SPDLOG_FMT_EXTERNAL "Use external fmt library instead of bundled" OFF) @@ -170,8 +171,14 @@ endif() add_library(spdlog::spdlog ALIAS spdlog) +set(SPDLOG_INCLUDES_LEVEL "") +if(SPDLOG_SYSTEM_INCLUDES) + set(SPDLOG_INCLUDES_LEVEL "SYSTEM") +endif() + + target_compile_definitions(spdlog PUBLIC SPDLOG_COMPILED_LIB) -target_include_directories(spdlog PUBLIC "$" +target_include_directories(spdlog ${SPDLOG_INCLUDES_LEVEL} PUBLIC "$" "$") target_link_libraries(spdlog PUBLIC Threads::Threads) spdlog_enable_warnings(spdlog) @@ -190,7 +197,7 @@ endif() add_library(spdlog_header_only INTERFACE) add_library(spdlog::spdlog_header_only ALIAS spdlog_header_only) -target_include_directories(spdlog_header_only INTERFACE "$" +target_include_directories(spdlog_header_only ${SPDLOG_INCLUDES_LEVEL} INTERFACE "$" "$") target_link_libraries(spdlog_header_only INTERFACE Threads::Threads) From a4e99175753d9fcdd7dcd803bb9b340107b73492 Mon Sep 17 00:00:00 2001 From: Alok Priyadarshi Date: Fri, 30 Dec 2022 05:20:10 -0800 Subject: [PATCH 6/8] feat(mpmc_blocking_q): add blocking dequeue without timeout (#2588) Use the new blocking dequeue to avoid unnecessarily waking up the thread pool every 10s. Fixes #2587 by replacing std::condition_variable::wait_for with std::condition_variable::wait as a workaroung for gcc 11.3 issue 101978. Co-authored-by: Alok Priyadarshi --- include/spdlog/details/mpmc_blocking_q.h | 26 ++++++++++++++++++++++-- include/spdlog/details/thread_pool-inl.h | 6 +----- tests/test_mpmc_q.cpp | 24 ++++++++++++++++++++-- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/include/spdlog/details/mpmc_blocking_q.h b/include/spdlog/details/mpmc_blocking_q.h index 785180c1..101ea8c0 100644 --- a/include/spdlog/details/mpmc_blocking_q.h +++ b/include/spdlog/details/mpmc_blocking_q.h @@ -49,7 +49,7 @@ public: push_cv_.notify_one(); } - // try to dequeue item. if no item found. wait up to timeout and try again + // dequeue with a timeout. // Return true, if succeeded dequeue item, false otherwise bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration) { @@ -66,6 +66,18 @@ public: return true; } + // blocking dequeue without a timeout. + void dequeue(T &popped_item) + { + { + std::unique_lock lock(queue_mutex_); + push_cv_.wait(lock, [this] { return !this->q_.empty(); }); + popped_item = std::move(q_.front()); + q_.pop_front(); + } + pop_cv_.notify_one(); + } + #else // apparently mingw deadlocks if the mutex is released before cv.notify_one(), // so release the mutex at the very end each function. @@ -87,7 +99,7 @@ public: push_cv_.notify_one(); } - // try to dequeue item. if no item found. wait up to timeout and try again + // dequeue with a timeout. // Return true, if succeeded dequeue item, false otherwise bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration) { @@ -102,6 +114,16 @@ public: return true; } + // blocking dequeue without a timeout. + void dequeue(T &popped_item) + { + std::unique_lock lock(queue_mutex_); + push_cv_.wait(lock, [this] { return !this->q_.empty(); }); + popped_item = std::move(q_.front()); + q_.pop_front(); + pop_cv_.notify_one(); + } + #endif size_t overrun_counter() diff --git a/include/spdlog/details/thread_pool-inl.h b/include/spdlog/details/thread_pool-inl.h index 369f30fe..dbd424ff 100644 --- a/include/spdlog/details/thread_pool-inl.h +++ b/include/spdlog/details/thread_pool-inl.h @@ -108,11 +108,7 @@ void SPDLOG_INLINE thread_pool::worker_loop_() bool SPDLOG_INLINE thread_pool::process_next_msg_() { async_msg incoming_async_msg; - bool dequeued = q_.dequeue_for(incoming_async_msg, std::chrono::seconds(10)); - if (!dequeued) - { - return true; - } + q_.dequeue(incoming_async_msg); switch (incoming_async_msg.msg_type) { diff --git a/tests/test_mpmc_q.cpp b/tests/test_mpmc_q.cpp index 3b8aec36..1540dcc8 100644 --- a/tests/test_mpmc_q.cpp +++ b/tests/test_mpmc_q.cpp @@ -43,6 +43,26 @@ TEST_CASE("dequeue-empty-wait", "[mpmc_blocking_q]") REQUIRE(delta_ms <= wait_ms + tolerance_wait); } +TEST_CASE("dequeue-full-nowait", "[mpmc_blocking_q]") +{ + spdlog::details::mpmc_blocking_queue q(1); + q.enqueue(42); + + int item = 0; + q.dequeue_for(item, milliseconds::zero()); + REQUIRE(item == 42); +} + +TEST_CASE("dequeue-full-wait", "[mpmc_blocking_q]") +{ + spdlog::details::mpmc_blocking_queue q(1); + q.enqueue(42); + + int item = 0; + q.dequeue(item); + REQUIRE(item == 42); +} + TEST_CASE("enqueue_nowait", "[mpmc_blocking_q]") { @@ -95,12 +115,12 @@ TEST_CASE("full_queue", "[mpmc_blocking_q]") for (int i = 1; i < static_cast(q_size); i++) { int item = -1; - q.dequeue_for(item, milliseconds(0)); + q.dequeue(item); REQUIRE(item == i); } // last item pushed has overridden the oldest. int item = -1; - q.dequeue_for(item, milliseconds(0)); + q.dequeue(item); REQUIRE(item == 123456); } From 3c93f7690a184847a277a1c40704aa1ee17dcba4 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sun, 1 Jan 2023 00:52:46 +0300 Subject: [PATCH 7/8] fix build: fix for freebsd (#2590) The build error was: include/spdlog/details/tcp_client.h:106:31: error: use of undeclared identifier 'IPPROTO_TCP' --- include/spdlog/details/tcp_client.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/spdlog/details/tcp_client.h b/include/spdlog/details/tcp_client.h index 0daff0eb..45883f34 100644 --- a/include/spdlog/details/tcp_client.h +++ b/include/spdlog/details/tcp_client.h @@ -16,6 +16,7 @@ #include #include #include +#include #include From 287a00d364990edbb621fe5e392aeb550135fb96 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 3 Jan 2023 09:54:50 -0800 Subject: [PATCH 8/8] Do not use LFS64 functions on linux/musl (#2589) On musl, off_t is 64bit always ( even on 32bit platforms ), therefore using LFS64 funcitons is not needed on such platforms. Moreover, musl has stopped providing aliases for these functions [1] which means it wont compile on newer musl systems. Therefore only use it on 32bit glibc/linux platforms and exclude musl like cygwin or OSX [1] https://git.musl-libc.org/cgit/musl/commit/?id=246f1c811448f37a44b41cd8df8d0ef9736d95f4 Signed-off-by: Khem Raj --- include/spdlog/details/os-inl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/spdlog/details/os-inl.h b/include/spdlog/details/os-inl.h index b9bab53c..7f22335f 100644 --- a/include/spdlog/details/os-inl.h +++ b/include/spdlog/details/os-inl.h @@ -236,8 +236,8 @@ SPDLOG_INLINE size_t filesize(FILE *f) # else int fd = ::fileno(f); # endif -// 64 bits(but not in osx or cygwin, where fstat64 is deprecated) -# if (defined(__linux__) || defined(__sun) || defined(_AIX)) && (defined(__LP64__) || defined(_LP64)) +// 64 bits(but not in osx, linux/musl or cygwin, where fstat64 is deprecated) +# if ((defined(__linux__) && defined(__GLIBC__)) || defined(__sun) || defined(_AIX)) && (defined(__LP64__) || defined(_LP64)) struct stat64 st; if (::fstat64(fd, &st) == 0) {