attribute说明:
- attribute是函数,attribute_value是attribute产生的值,如TimeStamp
- 可用于之后的filtering和formatting
- 分global、thread-specified和logger-specified 3类,第一类最常用,出现同名attribute时,优先级高的生效,优先级排序 global < thread-specified < logger-specified
- 全部使用pimpl idiom形式实现,可通过
logging::attribute_cast<>
将attribute转回原来的类型 - 所有已有值都在
attrs::xxx
工具函数
可使用logging::add_common_attributes()
添加默认attribute,共4种:
LineID
每输出一行log record,这个attribute会自加1TimeStamp
当前的时间ProcessID
进程IDThreadID
线程ID,单线程时,不会注册这个属性
函数内容简单说明:
void add_common_attributes()
{
boost::shared_ptr< logging::core > core = logging::core::get();
core->add_global_attribute("LineID", attrs::counter< unsigned int >(1));
core->add_global_attribute("TimeStamp", attrs::local_clock());
// other attributes skipped for brevity
}
除了这个函数,还有logging::add_console_log(std::cout)
和logging::add_file_log("test.log")
,参见网页
添加自定义attribute
默认sink
只使用severity一个attribute。用户使用filter、formatter和非默认sink时,需要自己添加abbtribute.
不同的logger会添加不同的abbtribute,如severity_logger
添加了Severity
attribute。
// We define our own severity levels
enum severity_level
{
normal,
notification,
warning,
error,
critical
};
void logging_function()
{
// The logger implicitly adds a source-specific attribute 'Severity'
// of type 'severity_level' on construction
src::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_SEV大致等价于
void manual_logging()
{
src::severity_logger< severity_level > slg;
logging::record rec = slg.open_record(keywords::severity = normal);
if (rec)
{
logging::record_ostream strm(rec);
strm << "A regular message";
strm.flush();
slg.push_record(boost::move(rec));
}
}
Logger-specific attributes
通常比global attribute
用得少,代码示例
void tagged_logging()
{
src::severity_logger< severity_level > slg;
slg.add_attribute("Tag", attrs::constant< std::string >("My tag value"));
BOOST_LOG_SEV(slg, normal) << "Here goes the tagged record";
}
thread-specific attributes
通常使用BOOST_LOG_SCOPED_THREAD_ATTR
添加
离开函数时,属性会被销毁!
void timed_logging()
{
BOOST_LOG_SCOPED_THREAD_ATTR("Timeline", attrs::timer());
src::severity_logger< severity_level > slg;
BOOST_LOG_SEV(slg, normal) << "Starting to time nested functions";
logging_function();
BOOST_LOG_SEV(slg, normal) << "Stopping to time nested functions";
}
attribute key word
attribute可通过key word的方式设置,格式
BOOST_LOG_ATTRIBUTE_KEYWORD(变量名,变量的keyword字符串,变量类型)
申请的应该是全局属性
代码示例:
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)
BOOST_LOG_ATTRIBUTE_KEYWORD(scope, "Scope", attrs::named_scope::value_type)
BOOST_LOG_ATTRIBUTE_KEYWORD(timeline, "Timeline", attrs::timer::value_type)
BOOST_LOG_SEV(slg, normal)
之后可直接使用
void init()
{
logging::add_console_log
(
std::clog,
keywords::format =
(
expr::stream
<< line_id /*使用之前注册的line_id对象*/
<< ": <" << severity /*使用之前注册的severity对象*/
<< "> " << expr::smessage
)
);
}
已定义attribute类型
类型 | 代码调用 | 示例 | 其他 |
---|---|---|---|
常量 | attrs::constant | attrs::constant< int >(-5) | attrs::make_constant(value) |
变量 | mutable_constant | attrs::mutable_constant< int > attr(-5) | |
计数 | attrs::counter | attrs::counter< int >(100, -5) | 可计数,也可生成序列,在多线程环境下生成的数字不一定有序 |
时间 | attrs::local_clock或attrs::utc_clock | attrs::local_clock() | 产生的attribute value是boost::posix_time::ptime |
计时 | attrs::timer | attrs::timer() | 产生的attribute value是boost::posix_time::ptime::time_duration_type |
作用域 | attrs::named_scope | attrs::named_scope() | 使用了__FILE__ 、__LINE__ 和BOOST_LOG_FUNCTION 等 |
当前进程id | attrs::current_process_id | attrs::current_process_id() | |
当前进程名 | attrs::current_process_name | attrs::current_process_name() | |
当前线程id | attrs::current_thread_id | attrs::current_thread_id | 返回值不一定是整数,具体看current_thread_id::value_type ,最好添加为全局属性 |
函数用作属性 | attrs::make_function | attrs::make_function(&std::rand) |
其他操作
类型 | 代码调用 | 示例 | 其他 |
---|---|---|---|
访问属性 | logging::visit | logging::visit< types >(attr, visitor_func()) | 官方说明 |
抽取属性 | logging::extract | logging::extract< int >(attr) | 官方说明 |
Scoped attributes
作用域分两种:logger和thread的
BOOST_LOG_SCOPED_LOGGER_ATTR(logger, attr_name, attr);
BOOST_LOG_SCOPED_THREAD_ATTR(attr_name, attr);
如果注册时,这个名字的属性已经存在,那么不会引发任何操作
scopeed属性十分有用,例如配合filter可用来区分何时输出到哪个sink
示例:
BOOST_LOG_DECLARE_GLOBAL_LOGGER(my_logger, src::logger_mt)
void foo()
{
// This log record will also be marked with the "Tag" attribute,
// whenever it is called from the A::bar function.
// It will not be marked when called from other places.
BOOST_LOG(get_my_logger()) << "A log message from foo";
}
struct A
{
src::logger m_Logger;
void bar()
{
// Set a thread-wide markup tag.
// Note the additional parentheses to form a Boost.PP sequence.
BOOST_LOG_SCOPED_THREAD_ATTR("Tag",
attrs::constant< std::string >("Called from A::bar"));
// This log record will be marked
BOOST_LOG(m_Logger) << "A log message from A::bar";
foo();
}
};
int main(int, char*[])
{
src::logger lg;
// Let's measure our application run time
BOOST_LOG_SCOPED_LOGGER_ATTR(lg, "RunTime", attrs::timer());
// Mark application start.
// The "RunTime" attribute should be nearly 0 at this point.
BOOST_LOG(lg) << "Application started";
// Note that no other log records are affected by the "RunTime" attribute.
foo();
A a;
a.bar();
// Mark application ending.
// The "RunTime" attribute will show the execution time elapsed.
BOOST_LOG(lg) << "Application ended";
return 0;
}
除了之前的两个宏外,还有两个宏
BOOST_LOG_SCOPED_LOGGER_TAG(logger, tag_name, tag_value);
BOOST_LOG_SCOPED_THREAD_TAG(tag_name, tag_value);
两都分别是BOOST_LOG_SCOPED_LOGGER_ATTR
和 BOOST_LOG_SCOPED_THREAD_ATTR
的简单封装,比如BOOST_LOG_SCOPED_THREAD_TAG("Tag", "Called from A::bar");
可替换之前代码中Tag
属性的代码。
官方网页-简单教程
官方网页-详细说明