From ff89f1476df4ac01f7b5f85c474093978d4a1090 Mon Sep 17 00:00:00 2001 From: gabime Date: Fri, 26 Apr 2019 18:14:59 +0300 Subject: [PATCH] Restored error_handler as std::function --- CMakeLists.txt | 2 +- example/example.cpp | 1 - include/spdlog/details/async_logger_impl.h | 121 --------------------- include/spdlog/logger.h | 8 +- tests/test_errors.cpp | 28 ++--- 5 files changed, 16 insertions(+), 144 deletions(-) delete mode 100644 include/spdlog/details/async_logger_impl.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 20669a00..5137907d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,7 @@ endif() option(SPDLOG_HEADER_ONLY "Header only version. Turn OFF to build as static lib" OFF) option(SPDLOG_BUILD_EXAMPLES "Build examples" ${SPDLOG_MASTER_PROJECT}) -option(SPDLOG_BUILD_BENCH "Build benchmarks (Requires https://github.com/google/benchmark.git to be installed)" OFF) +option(SPDLOG_BUILD_BENCH "Build benchmarks (Requires https://github.com/google/benchmark.git to be installed)" ON) option(SPDLOG_BUILD_TESTS "Build tests" ${SPDLOG_MASTER_PROJECT}) option(SPDLOG_FMT_EXTERNAL "Use external fmt library instead of bundled" OFF) option(SPDLOG_INSTALL "Generate the install target." ${SPDLOG_MASTER_PROJECT}) diff --git a/example/example.cpp b/example/example.cpp index 616a4d20..132494fd 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -12,7 +12,6 @@ #include "spdlog/async.h" #include "spdlog/sinks/stdout_color_sinks.h" - int main(int, char *[]) { using spdlog::sinks::stderr_color_sink_mt; diff --git a/include/spdlog/details/async_logger_impl.h b/include/spdlog/details/async_logger_impl.h deleted file mode 100644 index d3676960..00000000 --- a/include/spdlog/details/async_logger_impl.h +++ /dev/null @@ -1,121 +0,0 @@ -// -// Copyright(c) 2015 Gabi Melman. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) -// - -#pragma once - -// async logger implementation -// uses a thread pool to perform the actual logging - -#include "spdlog/details/thread_pool.h" - -#include -#include -#include - -template -inline spdlog::async_logger::async_logger( - std::string logger_name, It begin, It end, std::weak_ptr tp, async_overflow_policy overflow_policy) - : logger(std::move(logger_name), begin, end) - , thread_pool_(std::move(tp)) - , overflow_policy_(overflow_policy) -{ -} - -inline spdlog::async_logger::async_logger( - std::string logger_name, sinks_init_list sinks_list, std::weak_ptr tp, async_overflow_policy overflow_policy) - : async_logger(std::move(logger_name), sinks_list.begin(), sinks_list.end(), std::move(tp), overflow_policy) -{ -} - -inline spdlog::async_logger::async_logger( - std::string logger_name, sink_ptr single_sink, std::weak_ptr tp, async_overflow_policy overflow_policy) - : async_logger(std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy) -{ -} - -// send the log message to the thread pool -inline void spdlog::async_logger::sink_it_(details::log_msg &msg) -{ - if (auto pool_ptr = thread_pool_.lock()) - { - pool_ptr->post_log(shared_from_this(), msg, overflow_policy_); - } - else - { - throw spdlog_ex("async log: thread pool doesn't exist anymore"); - } -} - -// send flush request to the thread pool -inline void spdlog::async_logger::flush_() -{ - if (auto pool_ptr = thread_pool_.lock()) - { - pool_ptr->post_flush(shared_from_this(), overflow_policy_); - } - else - { - throw spdlog_ex("async flush: thread pool doesn't exist anymore"); - } -} - -// -// backend functions - called from the thread pool to do the actual job -// -inline void spdlog::async_logger::backend_log_(const details::log_msg &incoming_log_msg) -{ - try - { - for (auto &s : sinks_) - { - if (s->should_log(incoming_log_msg.level)) - { - s->log(incoming_log_msg); - } - } - } - catch (const std::exception &ex) - { - err_handler_(ex.what()); - } - catch (...) - { - err_handler_("Unknown exception in logger"); - } - - if (should_flush_(incoming_log_msg)) - { - backend_flush_(); - } -} - -inline void spdlog::async_logger::backend_flush_() -{ - try - { - for (auto &sink : sinks_) - { - sink->flush(); - } - } - catch (const std::exception &ex) - { - err_handler_(ex.what()); - } - catch (...) - { - err_handler_("Unknown exception in logger"); - } -} - -inline std::shared_ptr spdlog::async_logger::clone(std::string new_name) -{ - auto cloned = std::make_shared(std::move(new_name), sinks_.begin(), sinks_.end(), thread_pool_, overflow_policy_); - - cloned->set_level(this->level()); - cloned->flush_on(this->flush_level()); - cloned->set_error_handler(this->custom_err_handler_); - return std::move(cloned); -} diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index 58ae20e6..fdba2a11 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -27,12 +27,13 @@ #include #include #include +#include namespace spdlog { class logger { public: - using err_handler = void (*)(const std::string &msg); + using err_handler = std::function; template logger(std::string name, It begin, It end) : name_(std::move(name)) @@ -332,10 +333,7 @@ public: // default error handler. // print the error to stderr with the max rate of 1 message/minute. void err_handler_(const std::string &msg); - - // increment the message count (only if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)) - void incr_msg_counter_(details::log_msg &msg); - + const std::string name_; std::vector sinks_; spdlog::level_t level_{spdlog::logger::default_level()}; diff --git a/tests/test_errors.cpp b/tests/test_errors.cpp index f2d69777..24075634 100644 --- a/tests/test_errors.cpp +++ b/tests/test_errors.cpp @@ -41,18 +41,13 @@ TEST_CASE("default_error_handler", "[errors]]") struct custom_ex { }; - -static void custom_handler(const std::string &) -{ - throw custom_ex(); -} TEST_CASE("custom_error_handler", "[errors]]") { prepare_logdir(); std::string filename = "logs/simple_log.txt"; auto logger = spdlog::create("logger", filename, true); logger->flush_on(spdlog::level::info); - logger->set_error_handler(custom_handler); + logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); logger->info("Good message #1"); REQUIRE_THROWS_AS(logger->info("Bad format msg {} {}", "xxx"), custom_ex); @@ -64,7 +59,7 @@ TEST_CASE("default_error_handler2", "[errors]]") { spdlog::drop_all(); auto logger = spdlog::create("failed_logger"); - logger->set_error_handler(custom_handler); + logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex); } @@ -72,26 +67,26 @@ TEST_CASE("flush_error_handler", "[errors]]") { spdlog::drop_all(); auto logger = spdlog::create("failed_logger"); - logger->set_error_handler(custom_handler); + logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); REQUIRE_THROWS_AS(logger->flush(), custom_ex); } TEST_CASE("async_error_handler", "[errors]]") { prepare_logdir(); - + std::string err_msg("log failed with some msg"); std::string filename = "logs/simple_async_log.txt"; { spdlog::init_thread_pool(128, 1); auto logger = spdlog::create_async("logger", filename, true); - logger->set_error_handler([](const std::string &) { + logger->set_error_handler([=](const std::string &) { std::ofstream ofs("logs/custom_err.txt"); if (!ofs) { throw std::runtime_error("Failed open logs/custom_err.txt"); } - ofs << "log failed with some msg"; + ofs << err_msg; }); logger->info("Good message #1"); logger->info("Bad format msg {} {}", "xxx"); @@ -100,26 +95,27 @@ TEST_CASE("async_error_handler", "[errors]]") } spdlog::init_thread_pool(128, 1); REQUIRE(count_lines(filename) == 2); - REQUIRE(file_contents("logs/custom_err.txt") == "log failed with some msg"); + REQUIRE(file_contents("logs/custom_err.txt") == err_msg); } // Make sure async error handler is executed TEST_CASE("async_error_handler2", "[errors]]") { - prepare_logdir(); + prepare_logdir(); + std::string err_msg("This is async handler error message"); { spdlog::init_thread_pool(128, 1); auto logger = spdlog::create_async("failed_logger"); - logger->set_error_handler([](const std::string &) { + logger->set_error_handler([=](const std::string &) { std::ofstream ofs("logs/custom_err2.txt"); if (!ofs) throw std::runtime_error("Failed open logs/custom_err2.txt"); - ofs << "handler error message"; + ofs << err_msg; }); logger->info("Hello failure"); spdlog::drop("failed_logger"); // force logger to drain the queue and shutdown } spdlog::init_thread_pool(128, 1); - REQUIRE(file_contents("logs/custom_err2.txt") == "handler error message"); + REQUIRE(file_contents("logs/custom_err2.txt") == err_msg); }