boost.log(七)再谈过滤

再谈过滤

我们已经在前面的章节接触过滤,但只是浅尝辄止。我们现在能够添加日志记录并设置接收器的属性,我们需要建立复杂的过滤功能。让我们看下这个例子:


#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函数。

时间: 2024-10-08 15:47:41

boost.log(七)再谈过滤的相关文章

boost.log(二)过滤

日志过滤 严重级别可以使日志信息更加翔实,但通常也会成为筛选器用来过滤日志记录的工具.在Log库的core里面可以通过设置全局过滤器很容易地做到日志过滤,就像下面一样: #include <iostream> #include <boost/log/core.hpp> #include <boost/log/trivial.hpp> #include <boost/log/expressions.hpp> void init() { boost::log::

【linux基础】22、iptables layer7 实现七层应用过滤

一.iptables layer7简介 iptables layer7模块根据应用层协议对访问请求进行过滤 iptables工作于二,三,四层,本身不具备7层过滤功能,第三方开发者为iptables新增了layer7模块,能检测每一个报文的内部应用层协议是什么,并根据协议对请求进行过滤,但不支持对应用层协议的方法进行过滤. 需要对内核中的netfilter打layer7补丁并重新编译内核,对iptables打补丁,补上layer7模块并重新编译iptables 项目官网:http://l7-fi

OpenglES2.0 for Android:再谈纹理映射

OpenglES2.0 for Android:再谈纹理映射 前言 上一节我们实现了一个简单的纹理映射的例子--一个简单的贴图,这节我们来做一些稍微复杂一点的例子,最后再给我们前面的立方体做一个纹理. 纹理拉伸 重复拉伸方式 这种是经常使用的一张纹理拉伸方式,常用于绘制一些重复的元素,比如我们在游戏绘制一幅方格式的地图时.使用重复拉伸方式使得纹理能够根据目标平 面的大小自动重复,这样既不会失去纹理图的效果,也可以节省内存.如下图所示: 实现起来很简单,我们回到上节的项目,找到我们纹理的工具类Te

boost.log(四)记录器

记录器对象 在上个章节的接收器部分我们已经知道了boost.log库是如何存储日志的,现在是时候去尝试记录日志了.首先我们要创建一个记录器,这非常简单: boost::log::sources::logger lg; [注意]boost.log库在后台给记录器(logger)提供了写的功能,就如同BOOST_LOG_TRIVIAL 宏一样. 与接收器不同,记录器无须在任何地方注册,因为它们是直接与日志记录核心进行交互的.此外请注意boost.log库提供了两个版本的记录器: 线程安全的(logg

再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结

Angular 的数据绑定采用什么机制,详述原理? 脏检查机制.阐释脏检查机制,必须先了解如下问题. 单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别? ng-bind 单向数据绑定($scope -> view),用于数据显示,简写形式是 {{}}. 两者的区别在于页面没有加载完毕 {{val}} 会直接显示到页面,直到 Angular 渲染该绑定数据(这种行为有可能将 {{val}} 让用户看到):而 ng-bind 则是在 Angular 渲染完毕后将数据显示. ng-

boost.log要点笔记

常用简写: namespace logging = boost::log; namespace src = boost::log::sources; namespace expr = boost::log::expressions; namespace sinks = boost::log::sinks; namespace attrs = boost::log::attributes; namespace keywords = boost::log::keywords; 要点: 结构图要牢记在

Android 再谈handler

今天在做http网络事件的响应网络接收处理一般不能放在主线程中使用,目前也只会使用AsyncTask进行处理!之前虽然写过handler处理的一些文章但是发现全不会了!无奈~ 关于handler某位兄弟已经整理的很透彻了!现在引用下原话如下: Handler监听者框架:子线程是事件源,主线程是监听者.Handler作为子线程的监听器出现:主线程中生成Handler的子类,并重写handleMessage(Message msg) 方法,用来对子线程响应.子线程调用Hanlder的sendMess

再谈ORACLE CPROCD进程

罗列一下有关oprocd的知识点 oprocd是oracle在rac中引入用来fencing io的 在unix系统下,如果我们没有采用oracle之外的第三方集群软件,才会存在oprocd进程 在linux系统下,只有在10.2.0.4版本后,才会具有oprocd进程 在window下,不会存在oprocd 进程,但是会存在一个oraFenceService服务,用来实现相同的功能,该服务采用的技术是基于windows的,与oprocd不同 oprocd进程可以运行在两者模式下:fatal和n

从飞信群再谈时间管理

收邮件啊 快收邮件~取消飞信小群的当天晚上,便有几位小组组长跑到某某那如是说.虽然我没有做过调查,但是看到这样的情景,我想她们应该和我有一样的感觉,没有了飞信小群在一定程度上,不 -方 -便- 但是过了这一段时间之后,发现我们日常的学习并没有受到什么影响,反倒是比之前明显的改善了.下面谈谈我对这件事的看法. 首先我们还是有飞信大群的.因为不会经常通知,也就谈不上打扰,而且也保证了紧急情况下的及时性和效率.可小群不一样.小群的人数不多,但通知频繁.这样问题就随之来了.最近我的体会 优点一减少打扰