spdlog
Loading...
Searching...
No Matches
dup_filter_sink.h
Go to the documentation of this file.
1// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
2// Distributed under the MIT License (http://opensource.org/licenses/MIT)
3
4#pragma once
5
6#include "dist_sink.h"
9
10#include <cstdio>
11#include <mutex>
12#include <string>
13#include <chrono>
14
15// Duplicate message removal sink.
16// Skip the message if previous one is identical and less than "max_skip_duration" have passed
17//
18// Example:
19//
20// #include <spdlog/sinks/dup_filter_sink.h>
21//
22// int main() {
23// auto dup_filter = std::make_shared<dup_filter_sink_st>(std::chrono::seconds(5));
24// dup_filter->add_sink(std::make_shared<stdout_color_sink_mt>());
25// spdlog::logger l("logger", dup_filter);
26// l.info("Hello");
27// l.info("Hello");
28// l.info("Hello");
29// l.info("Different Hello");
30// }
31//
32// Will produce:
33// [2019-06-25 17:50:56.511] [logger] [info] Hello
34// [2019-06-25 17:50:56.512] [logger] [info] Skipped 3 duplicate messages..
35// [2019-06-25 17:50:56.512] [logger] [info] Different Hello
36
37namespace spdlog {
38namespace sinks {
39template<typename Mutex>
40class dup_filter_sink : public dist_sink<Mutex>
41{
42public:
43 template<class Rep, class Period>
45 : max_skip_duration_{max_skip_duration}
46 {}
47
48protected:
50 log_clock::time_point last_msg_time_;
52 size_t skip_counter_ = 0;
53
54 void sink_it_(const details::log_msg &msg) override
55 {
56 bool filtered = filter_(msg);
57 if (!filtered)
58 {
59 skip_counter_ += 1;
60 return;
61 }
62
63 // log the "skipped.." message
64 if (skip_counter_ > 0)
65 {
66 char buf[64];
67 auto msg_size = ::snprintf(buf, sizeof(buf), "Skipped %u duplicate messages..", static_cast<unsigned>(skip_counter_));
68 if (msg_size > 0 && static_cast<size_t>(msg_size) < sizeof(buf))
69 {
70 details::log_msg skipped_msg{msg.logger_name, level::info, string_view_t{buf, static_cast<size_t>(msg_size)}};
71 dist_sink<Mutex>::sink_it_(skipped_msg);
72 }
73 }
74
75 // log current message
77 last_msg_time_ = msg.time;
78 skip_counter_ = 0;
79 last_msg_payload_.assign(msg.payload.data(), msg.payload.data() + msg.payload.size());
80 }
81
82 // return whether the log msg should be displayed (true) or skipped (false)
83 bool filter_(const details::log_msg &msg)
84 {
85 auto filter_duration = msg.time - last_msg_time_;
86 return (filter_duration > max_skip_duration_) || (msg.payload != last_msg_payload_);
87 }
88};
89
92
93} // namespace sinks
94} // namespace spdlog
T assign(T... args)
void sink_it_(const details::log_msg &msg) override
Definition dist_sink.h:58
dup_filter_sink(std::chrono::duration< Rep, Period > max_skip_duration)
bool filter_(const details::log_msg &msg)
log_clock::time_point last_msg_time_
std::chrono::microseconds max_skip_duration_
void sink_it_(const details::log_msg &msg) override
Definition async.h:25
fmt::basic_string_view< char > string_view_t
Definition common.h:114
log_clock::time_point time
Definition log_msg.h:22
string_view_t payload
Definition log_msg.h:30
string_view_t logger_name
Definition log_msg.h:20