Boost 复杂日志过滤

Boost 复杂日志过滤

BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int)
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)

void init()
{
    //为所有槽设置公共的格式化器
    logging::formatter fmt = expr::stream
        << std::setw(6) << std::setfill('0') << line_id << std::setfill(' ')
        << ": <" << severity << ">\t"
        << expr::if_(expr::has_attr(tag_attr))
           [
               expr::stream << "[" << tag_attr << "] "
           ]
        << expr::smessage;
    ……
    sink->locked_backend()->add_stream(
        boost::make_shared< std::ofstream >("full.log"));

    sink->set_formatter(fmt);

    logging::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 || (expr::has_attr(tag_attr) && tag_attr == "IMPORTANT_MESSAGE"));
    ……
}
  • 两个槽:一个保存完整日志,另一个只保存重要日志
  • 两个槽使用相同的格式化器fmt
  • has_attr检查日志记录是否包含“ Tag”属性值

示例

#include <cstddef>
#include <string>
#include <ostream>
#include <fstream>
#include <iomanip>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/phoenix/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/sources/basic_logger.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/attributes/scoped_attribute.hpp>
#include <boost/log/utility/value_ref.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>


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;


//自定义严重等级
enum severity_level
{
	normal,
	notification,
	warning,
	error,
	critical
};


//重载<<运算符将严重等级插入流中
std::ostream& operator<< (std::ostream& strm, severity_level level)
{
	static const char* strings[] =
	{
		"normal",
		"notification",
		"warning",
		"error",
		"critical"
	};

	if (static_cast<std::size_t>(level) < sizeof(strings) / sizeof(*strings))
		strm << strings[level];
	else
		strm << static_cast<int>(level);

	return strm;
}


//定义属性关键字
BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int)
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)


void init()
{
	//为所有槽设置公共的格式化器
	logging::formatter fmt = expr::stream
		<< std::setw(6) << std::setfill('0') << line_id << std::setfill(' ')
		<< ": <" << severity << ">\t"
		<< expr::if_(expr::has_attr(tag_attr))
		[
			expr::stream << "[" << tag_attr << "] "
		]
	<< expr::smessage;

	//初始化槽
	typedef sinks::synchronous_sink< 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);

	logging::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 || (expr::has_attr(tag_attr) && tag_attr == "IMPORTANT_MESSAGE"));

	logging::core::get()->add_sink(sink);

	//添加常用属性
	logging::add_common_attributes();
}


void logging_function()
{
	src::severity_logger< severity_level > slg;

	BOOST_LOG_SEV(slg, normal) << "常规消息";
	BOOST_LOG_SEV(slg, warning) << "警告消息";
	BOOST_LOG_SEV(slg, critical) << "致命错误消息";

	{
		BOOST_LOG_SCOPED_THREAD_TAG("Tag", "IMPORTANT_MESSAGE");
		BOOST_LOG_SEV(slg, normal) << "重要消息";
	}
}


int main(int, char*[])
{
	init();

	logging_function();

	return 0;
}
  • 输出:

  • full.log:

  • important.log

自定义过滤器

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()));
    ……
}
  • 自定义过滤器接收封装在value_ref模板中的属性值
  • value_ref包含对指定类型的属性值的可选引用。如果日志记录包含所需类型的属性值,则引用有效
  • 可以直接使用封装后属性的关系运算符,因为如果引用无效,它们将自动返回false

示例

#include <cstddef>
#include <string>
#include <ostream>
#include <fstream>
#include <iomanip>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/phoenix/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/sources/basic_logger.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/attributes/scoped_attribute.hpp>
#include <boost/log/utility/value_ref.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>


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;


//自定义严重等级
enum severity_level
{
	normal,
	notification,
	warning,
	error,
	critical
};


//重载<<运算符将严重等级插入流中
std::ostream& operator<< (std::ostream& strm, severity_level level)
{
	static const char* strings[] =
	{
		"normal",
		"notification",
		"warning",
		"error",
		"critical"
	};

	if (static_cast<std::size_t>(level) < sizeof(strings) / sizeof(*strings))
		strm << strings[level];
	else
		strm << static_cast<int>(level);

	return strm;
}


//定义属性关键字
BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int)
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string)


//自定义过滤函数
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()
{
	//为所有槽设置公共的格式化器
	logging::formatter fmt = expr::stream
		<< std::setw(6) << std::setfill('0') << line_id << std::setfill(' ')
		<< ": <" << severity << ">\t"
		<< expr::if_(expr::has_attr(tag_attr))
		[
			expr::stream << "[" << tag_attr << "] "
		]
	<< expr::smessage;

	//初始化槽
	typedef sinks::synchronous_sink< 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);

	logging::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);

	namespace phoenix = boost::phoenix;
	sink->set_filter(phoenix::bind(&my_filter, severity.or_none(), tag_attr.or_none()));

	logging::core::get()->add_sink(sink);

	//添加常用属性
	logging::add_common_attributes();
}


void logging_function()
{
	src::severity_logger< severity_level > slg;

	BOOST_LOG_SEV(slg, normal) << "常规消息";
	BOOST_LOG_SEV(slg, warning) << "警告消息";
	BOOST_LOG_SEV(slg, critical) << "致命错误消息";

	{
		BOOST_LOG_SCOPED_THREAD_TAG("Tag", "IMPORTANT_MESSAGE");
		BOOST_LOG_SEV(slg, normal) << "重要消息";
	}
}


int main(int, char*[])
{
	init();

	logging_function();

	return 0;
}
  • 日志输出和前面案例相同。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值