码迷,mamicode.com
首页 > 其他好文 > 详细

boost.log(七)再谈过滤

时间:2015-05-07 11:55:29      阅读:1323      评论:0      收藏:0      [点我收藏+]

标签:

再谈过滤

    我们已经前面章节接触过滤浅尝辄止我们现在能够添加日志记录设置接收器属性我们需要建立复杂过滤功能让我们看下这个例子
#include <string>
#include <fstream>
#include <iomanip>
#include <boost/log/core.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/setup.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/attributes/scoped_attribute.hpp>
 
enum severity_level
{
normal,
notification,
warning,
error,
critical
};
 
BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)
BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int)
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
 
void init()
{
boost::log::formatter fmt = boost::log::expressions::stream
<< std::setw(6) << std::setfill(‘0‘) << line_id << std::setfill(‘ ‘)
<< ": <" << severity << ">\t"
<< boost::log::expressions::if_(boost::log::expressions::has_attr(tag_attr))
[
boost::log::expressions::stream << "[" << tag_attr << "] "
]
<< boost::log::expressions::smessage;
 
// Initialize sinks
typedef boost::log::sinks::synchronous_sink< boost::log::sinks::text_ostream_backend > text_sink;
boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();
 
sink->locked_backend()->add_stream(boost::make_shared< std::ofstream >("full.log"));
 
sink->set_formatter(fmt);
 
boost::log::core::get()->add_sink(sink);
 
sink = boost::make_shared< text_sink >();
 
sink->locked_backend()->add_stream(boost::make_shared< std::ofstream >("important.log"));
 
sink->set_formatter(fmt);
 
sink->set_filter(severity >= warning || (boost::log::expressions::has_attr(tag_attr) && tag_attr == "IMPORTANT_MESSAGE"));
 
boost::log::core::get()->add_sink(sink);
 
// Add attributes
boost::log::add_common_attributes();
}
 
void logging_function()
{
boost::log::sources::severity_logger< severity_level > slg;
 
BOOST_LOG_SEV(slg, normal) << "A regular message";
BOOST_LOG_SEV(slg, warning) << "Something bad is going on but I can handle it";
BOOST_LOG_SEV(slg, critical) << "Everything crumbles, shoot me now!";
 
{
BOOST_LOG_SCOPED_THREAD_TAG("Tag", "IMPORTANT_MESSAGE");
BOOST_LOG_SEV(slg, normal) << "An important message";
}
}
 
int main(int, char*[])
{
init();
 
logging_function();
 
return 0;
}

    在此示例中,我们创建了两个接收器。一个用于接收完整的日志文件,另一个则会过滤掉一些记录。两个接收器都使用了同一个格式化器fmt,所以它们都会保存相同格式的日志记录。格式化器的类型是一个类型擦除的函数对象,它在许多方面类似于boost::function 或 std::function ,但它从来不会为空。过滤器是有类型的函数对象。

    值得注意的是,格式化器本身就包含一个过滤器。正如你所看到的,格式化器的表达式中包含一个判断条件,这是目前唯一在日志记录包含了"Tag"属性。 has_attr  函数检查记录中是否包含"Tag"属性值并控制是否把它置入该文件

    我们进一步讨论两个接收器。第一接收器没有设置任何过滤器,这意味着它将把每个日志记录都保存到文件中。第二接收器调用了set_filter 函数,只保存日志严重级别不超过"warning",并且有一个属性"Tag",属性值必须为"IMPORTANT_MESSAGE"。过滤器的语法非常类似于C++,尤其是使用属性关键字的时候。

    如格式化器一样,过滤器也可以使用自定义函数。Boost.Phoenix在这种情况下非常有用,它的绑定实现可以与属性的占位符兼容。下面是修改后的例子:
bool my_filter(boost::log::value_ref< severity_level, tag::severity > const& level,
boost::log::value_ref< std::string, tag::tag_attr > const& tag)
{
return level >= warning || tag == "IMPORTANT_MESSAGE";
}
 
void init()
{
// ...
 
sink->set_filter(boost::phoenix::bind(&my_filter, severity.or_none(), tag_attr.or_none()));
 
// ...
}
    正如你可以看到,自定义格式化器接收属性值并纳入 value_ref  模板。如果日志记录包含所需类型的属性值,那么引用是有效的。在 my_filter 里面的关系操作符可以无条件地使用,因为如果引用无效它们会自动返回false。剩下的就是在绑定表达式的时候将severity和tag_attr的值传递给my_filter函数。

boost.log(七)再谈过滤

标签:

原文地址:http://www.cnblogs.com/zhangpanyi/p/4484306.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!