I've created a Logger class that uses boost::log. The class keeps track of the current severity level set. When adding a severity filter to a sink, I'd like that the filter do the filtering based on the current severity, as opposed to the one when the sink was added.
class Logger
{
public:
typedef /* ... */ severity_level;
//(...)
static severity_level currentSeverityLevel() {return severity_level_var;}
private:
severity_level severity_level_var;
//(...)
};
When adding a filter, as below, currentSeverityLevel() is called only when the filter is set.
console_sink->set_filter( severity >= Logger::currentSeverityLevel());
I would like such a filter, but that actually calls the function every time. As per the documentation, one can define a function to be used as filter (see below), but it requires the use of boost::phoenix. Surely there must be a simpler way? Something like a lambda expression? The set_filter function sets a filter type, which in turn sets a boost light_function, which is a "lightweight alternative of Boost.Function". It seems, then, that it would be straight forward to set something similar to a Lambda expression/Boost.Function
bool my_filter(logging::value_ref< severity_level, tag::severity > const& level,
logging::value_ref< std::string, tag::tag_attr > const& tag)
{
return level >= warning || tag == "IMPORTANT_MESSAGE";
}
void init()
{
// ...
namespace phoenix = boost::phoenix;
sink->set_filter(phoenix::bind(&my_filter, severity.or_none(), tag_attr.or_none()));
// ...
}
In order to call
Logger::currentSeverityLevel
on every log record you have to turn it into a Boost.Phoenix expression so that it is evaluated lazily. The simplest way to do this is to usephoenix::bind
.You can achieve a cleaner syntax if you create a lazy wrapper for your function as described here.
Also, you can save references to external objects in Boost.Phoenix expressions.
This filter will read the
severity_level_var
value on every call. However, this approach makes it more difficult to ensure thread safe operations on theseverity_level_var
variable. This is not done in yourcurrentSeverityLevel
implementation, so I assume thread safety is either not required or achieved by other means.