设置boost :: log严重性过滤器以调用函数,而不是使用恒定的严重性 [英] Setting boost::log severity filter to call a function, as opposed to using a constant severity
问题描述
我创建了一个使用boost :: log的Logger类.该类跟踪当前的严重性级别集.在向接收器添加严重性过滤器时,我希望过滤器根据当前的严重性进行过滤,而不是在添加接收器时进行过滤.
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;
//(...)
};
添加过滤器时,如下所示,仅在设置过滤器时才调用currentSeverityLevel().
When adding a filter, as below, currentSeverityLevel() is called only when the filter is set.
console_sink->set_filter( severity >= Logger::currentSeverityLevel());
我想要一个这样的过滤器,但是实际上每次都会调用该函数.根据文档,可以定义一个用作过滤器的函数(请参见下文),但是它需要使用boost :: phoenix.当然必须有一种更简单的方法吗?有点像lambda表达式? set_filter函数设置一个过滤器类型,后者又设置一个boost light_function,它是"Boost.Function的轻量级替代".这样看来,直接设置类似于Lambda表达式/Boost.Function的东西
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()));
// ...
}
推荐答案
要在每个日志记录上调用Logger::currentSeverityLevel
,您必须将其转换为Boost.Phoenix表达式,以便对其进行延迟求值.最简单的方法是使用phoenix::bind
.
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 use phoenix::bind
.
console_sink->set_filter(
severity >= phoenix::bind(&Logger::currentSeverityLevel)
);
如果按照此外,您还可以在Boost.Phoenix表达式中保存对外部对象的引用.
Also, you can save references to external objects in Boost.Phoenix expressions.
console_sink->set_filter(severity >= phoenix::ref(severity_level_var));
此过滤器将在每次调用时读取severity_level_var
值.但是,此方法使确保severity_level_var
变量上的线程安全操作更加困难.在您的currentSeverityLevel
实现中并没有做到这一点,因此我假设不需要或通过其他方式实现线程安全.
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 the severity_level_var
variable. This is not done in your currentSeverityLevel
implementation, so I assume thread safety is either not required or achieved by other means.
这篇关于设置boost :: log严重性过滤器以调用函数,而不是使用恒定的严重性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!