ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

boost.log教程:core facilities

2019-05-13 11:55:09  阅读:439  来源: 互联网

标签:core logging log attribute record sink boost


Logging records

logging record中的所有信息,包括message text,都会被filters, formatters 和 sinks处理。
logging record特性:

  • 不能复制,只能被移动boost::move()。它由logging core在filter之后创建,此时内容为空,随后attribute value会由attribute生成并添加到log record
  • logging record可在formatting和sink时继续添加attributes
  • 多线程环境中,logging record与创建它的线程绑定,所以logging record不能在线程中移动。

读取这些信息的方式有几种:

通过 logging::visitlogging::value_ref

更详细参见网页

enum severity_level { ... };
std::ostream& operator<< (std::ostream& strm, severity_level level);

struct print_visitor
{
    typedef void result_type;
    result_type operator() (severity_level level) const
    {
        std::cout << level << std::endl;
    };
};

// Prints severity level through visitation API
void print_severity_visitation(logging::record const& rec)
{
    logging::visit< severity_level >("Severity", rec, print_visitor());
}

// Prints severity level through extraction API
void print_severity_extraction(logging::record const& rec)
{
    logging::value_ref< severity_level > level = logging::extract< severity_level >("Severity", rec);
    std::cout << level << std::endl;
}

通过 attribute_values访问所有属性

更详细参见网页

// Prints severity level by searching the attribute values
void print_severity_lookup(logging::record const& rec)
{
    logging::attribute_value_set const& values = rec.attribute_values();
    logging::attribute_value_set::const_iterator it = values.find("Severity");
    if (it != values.end())
    {
        logging::attribute_value const& value = it->second;

        // A single attribute value can also be visited or extracted
        std::cout << value.extract< severity_level >() << std::endl;
    }
}

直接通过下标方式访问

BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)

// Prints severity level by using the subscript operator
void print_severity_subscript(logging::record const& rec)
{
    // Use the attribute keyword to communicate the name and type of the value
    logging::value_ref< severity_level, tag::severity > level = rec[severity];
    std::cout << level << std::endl;
}

Record view

与logging record相似, record用来填充信息,record view用来后续处理:

  • record view不可变,可防止formatter及sink修改它
  • record view可复制,因为内容不可改,使用浅复制成本很低

boost会自动在lock函数被调用时,为record创建record view:

  • record view不会绑定到线程
  • record 会在lock结束后变空值,因为record只被处理一次

Logging core

logging core是库的核心,提供:

  • 维护全局和各线程的attribute sets
  • 处理log record的全局过滤
  • 应用sink的filter在sink间传递log record
  • 提供全局的exception handler
  • 提供全局的log record输入口
  • 提供flush强制输出

访问方式

boost::shared_ptr< logging::core > core = logging::core::get();

Attribute sets

添加/删除全局属性add_global_attributeremove_global_attribute
添加/删除线程属性add_thread_attributeremove_thread_attribute

void foo()
{
    boost::shared_ptr< logging::core > core = logging::core::get();

    // Add a global attribute
	// 返回值第一个参数是其被添加后的索引,bool代表是否添加成功
    std::pair< logging::attribute_set::iterator, bool > res =
        core->add_global_attribute("LineID", attrs::counter< unsigned int >());
    // Do something ...
    // Remove the added attribute
    core->remove_global_attribute(res.first);
}

logging::core的所有方法都是线程安全的,但索引不能保证线程安全
获取/设置全局属性get_global_attributesset_global_attributes
获取/设置线程属性get_thread_attributesset_thread_attributes


Global filtering

filter读入一组参数,返回此record是否通过
设置/清除filter的函数set_filter/ reset_filter,filter没有设置,相当于所有log record可通过
通过set_logging_enabled,可设置filter是否生效,比较设置filter更高效。


Sink management

添加/删除sink的函数,add_sinkremove_sink。添加的sink会保存到logging core中,但sink的执行顺序是不确定的。

void foo()
{
    boost::shared_ptr< logging::core > core = logging::core::get();

    // Set a sink that will write log records to the console
    boost::shared_ptr< sinks::text_ostream_backend > backend =
        boost::make_shared< sinks::text_ostream_backend >();
    backend->add_stream(
        boost::shared_ptr< std::ostream >(&std::clog, boost::null_deleter()));

    typedef sinks::unlocked_sink< sinks::text_ostream_backend > sink_t;
    boost::shared_ptr< sink_t > sink = boost::make_shared< sink_t >(backend);
    core->add_sink(sink);

    // ...

    // Remove the sink
    core->remove_sink(sink);
}

sink的详细说明见frontendbackend


Exception handling

添加异常处理类,通过set_exception_handler设置,其参数是无参数函数,在catch语句中被调用。
logging core中的异常处理类只应该处理通用错误。
Logging sinks 和 sources 可做更细致的异常处理,参见
sink异常处理source异常处理

struct my_handler
{
    typedef void result_type;

    void operator() (std::runtime_error const& e) const
    {
        std::cout << "std::runtime_error: " << e.what() << std::endl;
    }
    void operator() (std::logic_error const& e) const
    {
        std::cout << "std::logic_error: " << e.what() << std::endl;
        throw;
    }
};

void init_exception_handler()
{
    // Setup a global exception handler that will call my_handler::operator()
    // for the specified exception types
    logging::core::get()->set_exception_handler(logging::make_exception_handler<
        std::runtime_error,  /*处理的错误类型*/
        std::logic_error
    >(my_handler()));
}

Feeding log records

logging core最重要的功能之一就是创建和推送log record,实现函数分别为open_recordpush_record.

  • open_record收集global, thread-specific 和 source-specific的属性,判断是否会被filter掉,如果没有被filter掉(至少有一个sink接收这个record),函数会返回一个log record对象
  • push_record在由open_record获得的record对象填写完内容后调用。之后record view对象会从record对象中生成,并传给接收它的多个sink,这个过程中会发生formatting及保存到文件等操作,视情况而不同。随后record对象被销毁。
void logging_function(logging::attribute_set const& attrs)
{
    boost::shared_ptr< logging::core > core = logging::core::get();

    // Attempt to open a log record
    logging::record rec = core->open_record(attrs);
    if (rec)
    {
        // Ok, the record is accepted. Compose the message now.
        logging::record_ostream strm(rec);
        strm << "Hello, World!";
        strm.flush();

        // Deliver the record to the sinks.
        core->push_record(boost::move(rec));
    }
}

官方说明

标签:core,logging,log,attribute,record,sink,boost
来源: https://blog.csdn.net/LaineGates/article/details/90169799

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有