Fix dup filter

This commit is contained in:
gabime 2019-06-27 17:17:25 +03:00
parent 5dd260c336
commit 7f3b5fb84d

View File

@ -7,24 +7,30 @@
#include "spdlog/details/null_mutex.h" #include "spdlog/details/null_mutex.h"
#include "spdlog/details/log_msg.h" #include "spdlog/details/log_msg.h"
#include <mutex>
#include <string> #include <string>
#include <chrono> #include <chrono>
// Duplicate remove sink. // Duplicate message removal sink.
// Filter the message if previous one is identical and less than max max_skip_duration have passed // Skip the message if previous one is identical and less than "max_skip_duration" have passed
// //
// Example: // Example:
// auto d = std::make_shared<dup_filter_sink_st>(std::chrono::seconds(5)); //
// d->add_sink(std::make_shared<stdout_color_sink_mt>()); // #include "spdlog/sinks/dup_filter_sink.h"
// spdlog::logger l("logger", d); //
// int main() {
// auto dup_filter = std::make_shared<dup_filter_sink_st>(std::chrono::seconds(5));
// dup_filter->add_sink(std::make_shared<stdout_color_sink_mt>());
// spdlog::logger l("logger", dup_filter);
// l.info("Hello"); // l.info("Hello");
// l.info("Hello"); // l.info("Hello");
// l.info("Hello"); // l.info("Hello");
// l.info("Different Hello"); // l.info("Different Hello");
// }
// //
// Will produce: // Will produce:
// [2019-06-25 17:50:56.511] [logger] [info] Hello // [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 // [2019-06-25 17:50:56.512] [logger] [info] Different Hello
@ -36,54 +42,51 @@ class dup_filter_sink : public dist_sink<Mutex>
{ {
public: public:
template<class Rep, class Period> template<class Rep, class Period>
explicit dup_filter_sink(std::chrono::duration<Rep, Period> max_ignore_duration) explicit dup_filter_sink(std::chrono::duration<Rep, Period> max_skip_duration)
: max_skip_duration_{max_ignore_duration} : max_skip_duration_{max_skip_duration}
, last_msg_time_{log_clock::now()}
, skip_counter_{0}
{} {}
protected: protected:
std::chrono::microseconds max_skip_duration_; std::chrono::microseconds max_skip_duration_;
log_clock::time_point last_msg_time_; log_clock::time_point last_msg_time_;
size_t skip_counter_;
std::string last_msg_payload_; std::string last_msg_payload_;
size_t skip_counter_ = 0;
void sink_it_(const details::log_msg &msg) override void sink_it_(const details::log_msg &msg) override
{ {
auto msg_time = msg.time; bool filtered = filter_(msg);
auto delta_time = msg_time - last_msg_time_; if(!filtered)
last_msg_time_ = msg_time;
if (delta_time < max_skip_duration_ && last_msg_payload_ == msg.payload)
{ {
skip_counter_++; skip_counter_ += 1;
return; return;
} }
// got different message from the previous // log the "skipped.." message
if(skip_counter_ > 0) if(skip_counter_ > 0)
{ {
fmt::basic_memory_buffer<char, 80> buf; fmt::basic_memory_buffer<char, 64> buf;
fmt::format_to(buf, "{} duplicate messages..", skip_counter_); 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()}}; details::log_msg skipped_msg{msg.logger_name, msg.level, string_view_t{buf.data(), buf.size()}};
dist_sink<Mutex>::sink_it_(skipped_msg);
// log the skip notification
for (auto &sink : dist_sink<Mutex>::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()); // log current message
dist_sink<Mutex>::sink_it_(msg); dist_sink<Mutex>::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<std::mutex>; using dup_filter_sink_mt = dup_filter_sink<std::mutex>;
using dup_filter_sink_st = dup_filter_sink<details::null_mutex>; using dup_filter_sink_st = dup_filter_sink<details::null_mutex>;
} // namespace sinks } // namespace sinks
} // namespace spdlog } // namespace spdlog