设置boost :: log严重性过滤器以调用函数,而不是使用恒定的严重性 [英] Setting boost::log severity filter to call a function, as opposed to using a constant severity

查看:72
本文介绍了设置boost :: log严重性过滤器以调用函数,而不是使用恒定的严重性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆