Boost.log 教程:attribute

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会自加1
  • TimeStamp当前的时间
  • ProcessID进程ID
  • ThreadID线程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添加了Severityattribute。

// 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::constantattrs::constant< int >(-5)attrs::make_constant(value)
变量mutable_constantattrs::mutable_constant< int > attr(-5)
计数attrs::counterattrs::counter< int >(100, -5)可计数,也可生成序列,在多线程环境下生成的数字不一定有序
时间attrs::local_clock或attrs::utc_clockattrs::local_clock()产生的attribute value是boost::posix_time::ptime
计时attrs::timerattrs::timer()产生的attribute value是boost::posix_time::ptime::time_duration_type
作用域attrs::named_scopeattrs::named_scope()使用了__FILE____LINE__BOOST_LOG_FUNCTION
当前进程idattrs::current_process_idattrs::current_process_id()
当前进程名attrs::current_process_nameattrs::current_process_name()
当前线程idattrs::current_thread_idattrs::current_thread_id返回值不一定是整数,具体看current_thread_id::value_type,最好添加为全局属性
函数用作属性attrs::make_functionattrs::make_function(&std::rand)

其他操作

类型代码调用示例其他
访问属性logging::visitlogging::visit< types >(attr, visitor_func())官方说明
抽取属性logging::extractlogging::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_ATTRBOOST_LOG_SCOPED_THREAD_ATTR的简单封装,比如BOOST_LOG_SCOPED_THREAD_TAG("Tag", "Called from A::bar");可替换之前代码中Tag属性的代码。
官方网页-简单教程
官方网页-详细说明

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值