From 0aeaf9e28e080c4cc1754571370b9e0654c7137f Mon Sep 17 00:00:00 2001 From: Alexander Zilberkant Date: Thu, 11 May 2017 23:52:42 +0300 Subject: [PATCH] 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) { - now = details::os::now(); - sleep_or_yield(now, last_op_time); + 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 + { +#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 +///////////////////////////////////////////////////////////////////////////////