Filters - Quill v11.0.2 - C++ Logging Library (original) (raw)

Filters are used to selectively control which log statements are sent to specific Sinks based on defined criteria.

Each Sink can be associated with one or multiple Filter objects. These filters allow customization of log statement handling, such as filtering by log level or other criteria.

By default, a logger sends all log messages to its Sinks. Filters provide a way to intercept and selectively process log records before they are outputted.

A filter is implemented as a callable object that evaluates each log statement on the backend thread and returns a boolean value. When the filter returns true, the log statement is forwarded to the Sink; when false, the log statement is discarded.

Filtering Logs with the Built-In Filter

1#include "quill/Backend.h" 2#include "quill/Frontend.h" 3#include "quill/LogMacros.h" 4#include "quill/Logger.h" 5#include "quill/sinks/ConsoleSink.h" 6 7int main() 8{ 9 quill::Backend::start(); 10 11 quill::Logger* logger = quill::Frontend::create_or_get_logger( 12 "root", quill::Frontend::create_or_get_sinkquill::ConsoleSink("sink_id_1")); 13 14 LOG_INFO(logger, "This is a log info example {}", 123); 15 16 // Apply filter to the sink. This is thread-safe but to avoid setting the filter before the 17 // backend has processed the earlier log message we flush first 18 logger->flush_log(); 19 quill::Frontend::get_sink("sink_id_1")->set_log_level_filter(quill::LogLevel::Error); 20 LOG_INFO(logger, "This message is filtered"); 21 22 logger->flush_log(); 23 quill::Frontend::get_sink("sink_id_1")->set_log_level_filter(quill::LogLevel::TraceL3); 24 LOG_INFO(logger, "This is a log info example {}", 456); 25}

Creating a Custom Log Filter

1#include "quill/Backend.h" 2#include "quill/Frontend.h" 3#include "quill/LogMacros.h" 4#include "quill/Logger.h" 5#include "quill/filters/Filter.h" 6#include "quill/sinks/ConsoleSink.h" 7 8#include 9#include 10#include 11#include 12 13/** 14 * This example demonstrates the creation usage of a user defined filter. 15 * When a filter is applied, log messages are still enqueued from the frontend to the backend. 16 * Subsequently, the backend dynamically filters them based on a given condition. 17 / 18 19class UserFilter : public quill::Filter 20{ 21public: 22 UserFilter() : quill::Filter("filter_1") {}; 23 24 bool filter(quill::MacroMetadata const /** log_metadata /, uint64_t / log_timestamp /, 25 std::string_view / thread_id /, std::string_view / thread_name /, 26 std::string_view / logger_name /, quill::LogLevel log_level, 27 std::string_view log_message, std::string_view / log_statement **/) noexcept override 28 { 29 // for example filter out duplicate log files 30 bool is_different = true; 31 32 if ((last_log_level == log_level) && (log_message == last_message)) 33 { 34 is_different = false; 35 } 36 37 last_message = log_message; 38 last_log_level = log_level; 39 40 // return true to log the message, false otherwise 41 return is_different; 42 } 43 44private: 45 std::string last_message; 46 quill::LogLevel last_log_level{quill::LogLevel::None}; 47}; 48 49int main() 50{ 51 // Start the backend thread 52 quill::BackendOptions backend_options; 53 quill::Backend::start(backend_options); 54 55 // Frontend 56 auto console_sink = quill::Frontend::create_or_get_sinkquill::ConsoleSink("sink_id_1"); 57 58 // Add the filter - adding filters is thread safe and can be called anytime 59 console_sink->add_filter(std::make_unique()); 60 61 quill::Logger* logger = quill::Frontend::create_or_get_logger("root", std::move(console_sink)); 62 63 // Change the LogLevel to send everything 64 logger->set_log_level(quill::LogLevel::TraceL3); 65 66 LOG_INFO(logger, "This is a log info example {}", 123); 67 LOG_INFO(logger, "This is a log info example {}", 123); 68 LOG_INFO(logger, "This is a log info example {}", 123); 69 LOG_INFO(logger, "This is a log info example {}", 123); 70 LOG_INFO(logger, "This is a log info example {}", 456); 71 LOG_INFO(logger, "This is a log info example {}", 123); 72}