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;
}
自定义过滤器
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;
}