boost::log

来源:互联网 发布:淘宝女童丝袜模特 编辑:程序博客网 时间:2024/05/22 05:27

1.最平常的写日志

#include <boost/log/trivial.hpp>int main(int, char*[]){BOOST_LOG_TRIVIAL(trace) << "A trace severity message";BOOST_LOG_TRIVIAL(debug) << "A debug severity message";BOOST_LOG_TRIVIAL(info) << "An informational severity message";BOOST_LOG_TRIVIAL(warning) << "A warning severity message";BOOST_LOG_TRIVIAL(error) << "An error severity message";BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";return 0;}
  信息会打印到控制台,类似std::cout,但有如下优势:
  1).不光有日志信息,输出还包含时间戳,当前线程标识,安全等级;
  2).不同线程同时写日志是安全的;
  3).可以应用过滤。

   添加过滤日志:

void init(){logging::core::get()->set_filter(    logging::trivial::severity >= logging::trivial::info);}int main(int, char*[]){init();BOOST_LOG_TRIVIAL(trace) << "A trace severity message";BOOST_LOG_TRIVIAL(debug) << "A debug severity message";BOOST_LOG_TRIVIAL(info) << "An informational severity message";BOOST_LOG_TRIVIAL(warning) << "A warning severity message";BOOST_LOG_TRIVIAL(error) << "An error severity message";BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";return 0;}
   等级大于info的才会输出,其他的忽略。

2. Setting up sinks

  sink由两个类组成:
    1).frontend:负责所有sink的各种常见任务,如线程同步模型,过滤,针对text-based sink的格式化;
    2).backend:实现特定sink的所有事情,如写到一个文件。

  synchronous_sink:支持多线程同时写日志,必要时会自动阻塞。

  text_ostream_backend类可以将格式化的日志项写到STL兼容的stream。例:

#include <boost/core/null_deleter.hpp>// We have to provide an empty deleter to avoid destroying the global stream objectboost::shared_ptr< std::ostream > stream(&std::clog, boost::null_deleter());sink->locked_backend()->add_stream(stream);
  text_ostream_backend支持添加多个流。对于这个sink来说这种方式可以复制输出到控制台和文件,而这个过程中对于每个日志项过滤/格式化和其他类库只有一次开销。
locked_backend成员函数调用sink的backend。它被用来得到一个对backend的线程安全的调用,所有sink fronteds可以提供改成员函数。这个函数返回一个智能指针,并且只要它存在,backend就是被锁的。只有一个例外,unlocked_sink frontend,它不是同步的,而且只是简单返回一个未锁的指向backend的指针。

3.Creating loggers and writing logs

创建logger对象
    src::logger lg;
    类库提供了两个版本的logger:线程安全/非线程安全。非线程安全的logger当使用不同logger实例写日志时是安全的。也就也意味着每个线程都要建立一个logger实例。线程安全的logger可以多个线程同时写,但是这个过程会包含锁,降低效率。线程安全的logger类型都带有_mt后缀。

全局logger对象
    BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, src::logger_mt)
    src::logger_mt& lg = my_logger::get();    //get本身是线程安全的,不用添加同步

写日志

logging::record rec = lg.open_record();if (rec){logging::record_ostream strm(rec);strm << "Hello, World!";strm.flush();lg.push_record(boost::move(rec));}

或者使用宏定义

BOOST_LOG(lg) << "Hello, World!";
全部例子

/* *          Copyright Andrey Semashev 2007 - 2015. * Distributed under the Boost Software License, Version 1.0. *    (See accompanying file LICENSE_1_0.txt or copy at *          http://www.boost.org/LICENSE_1_0.txt) */#include <boost/move/utility.hpp>#include <boost/log/sources/logger.hpp>#include <boost/log/sources/record_ostream.hpp>#include <boost/log/sources/global_logger_storage.hpp>#include <boost/log/utility/setup/file.hpp>#include <boost/log/utility/setup/common_attributes.hpp>namespace logging = boost::log;namespace src = boost::log::sources;namespace keywords = boost::log::keywords;BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, src::logger_mt)void logging_function1(){src::logger lg;//[ example_tutorial_logging_manual_logginglogging::record rec = lg.open_record();if (rec){    logging::record_ostream strm(rec);    strm << "Hello, World!";    strm.flush();    lg.push_record(boost::move(rec));}//]}void logging_function2(){src::logger_mt& lg = my_logger::get();BOOST_LOG(lg) << "Greetings from the global logger!";}int main(int, char*[]){logging::add_file_log("sample.log");logging::add_common_attributes();logging_function1();logging_function2();return 0;}

编译链接:

c++ -g -std=c++11 -Wall -DBOOST_ALL_DYN_LINK -DBOOST_LOG_DYN_LINK -o ./main.o -c ./main.cc  c++ -g -std=c++11 ./main.o -o main  -rdynamic -lpthread -lboost_log_setup  -lboost_log -lboost_filesystem  -lboost_system -lboost_thread

4. Adding more information to log: Attributes

logging::add_common_attributes();
    添加LineID,TimeStamp,ProcessID,ThreadID

其相当于如下代码:
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}
可以为参数定义占位符

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)

5. Log record formatting
Lambda-style formatters 示例1:

void init(){logging::add_file_log(    keywords::file_name = "sample_%N.log",    // This makes the sink to write log records that look like this:    // 1: <normal> A normal severity message    // 2: <error> An error severity message    keywords::format =    (        expr::stream            << expr::attr< unsigned int >("LineID")            << ": <" << logging::trivial::severity            << "> " << expr::smessage    ));}

示例2

void init(){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 >("sample.log"));sink->set_formatter(    expr::stream           // line id will be written in hex, 8-digits, zero-filled        << std::hex << std::setw(8) << std::setfill('0') << expr::attr< unsigned int >("LineID")        << ": <" << logging::trivial::severity        << "> " << expr::smessage);logging::core::get()->add_sink(sink);}

Boost.Format-style formatters
示例1:

void init(){    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 >("sample.log"));    // This makes the sink to write log records that look like this:    // 1: <normal> A normal severity message    // 2: <error> An error severity message    sink->set_formatter    (        expr::format("%1%: <%2%> %3%")            % expr::attr< unsigned int >("LineID")            % logging::trivial::severity            % expr::smessage    );    logging::core::get()->add_sink(sink);}

6. Filtering revisited

示例:

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(){// Setup the common formatter for all sinkslogging::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;// Initialize sinkstypedef 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);// Add attributeslogging::add_common_attributes();}void logging_function(){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_SCOPED_THREAD_TAG("Tag", "IMPORTANT_MESSAGE");    BOOST_LOG_SEV(slg, normal) << "An important message";}}int main(int, char*[]){init();logging_function();return 0;}

示例中初始化了两个sink,两个设置了相同的记录格式。第二个设置了过滤,要求级别大于warning或者包含tag参数,且参数为IMPORTANT_MESSAGE。在调用logger对象写日志的时候可以用BOOST_LOG_SCOPED_THREAD_TAG("Tag", "IMPORTANT_MESSAGE");设置tag。


总结:

一般init的流程

1.新建backend;

2.新建sink,将backend添加到sink;

3.配置sink并将添加到core中。


一般调用的流程

1.定义全局变量

2.调用全局变量



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 大门牙的缝蛀了怎么办 最里面的牙烂了怎么办 牙齿蛀了个洞怎么办办 牙齿痛怎么办才能治好? 门牙牙齿蛀掉了怎么办 吃了辣的牙齿痛怎么办 牙颈部楔状缺损怎么办 牙齿磨了很疼怎么办 小孩牙有窟窿疼怎么办 西瓜吃多了尿不停怎么办 吃了个西瓜不停拉肚子怎么办 例假完了又来了怎么办 肾上面有个肿瘤怎么办 膀胱壁毛糙增厚怎么办 痔疮手术后尿不出来怎么办 小牛肚一天不尿怎么办 小孩拉肚一直不好怎么办 尿涨但是尿很少怎么办 十四岁尿血医生说是肾炎怎么办 吃肉反胃想吐怎么办 母牛排尿带血尿发烧怎么办 4岁发烧40度怎么办 狗狗拉肚子咳漱哮喘怎么办 拉肚子拉脱水人无力怎么办 孕中期拉稀拉水怎么办 吃坏肚子拉稀水怎么办 手上起小疙瘩疼怎么办 手上长东西很痛怎么办 七八十斤猪拉稀怎么办 宝宝扁桃体化脓反复发烧怎么办 骑单车后膝盖痛怎么办 孩子一运动就喘怎么办 小孩晚上咳嗽很厉害怎么办 1岁宝宝夜里咳嗽怎么办 咳嗽咳的胸疼怎么办 儿童又咳又喘怎么办 咳嗽咳到胸口痛怎么办 咳嗽咳得肋骨疼怎么办 孕妇咳嗽咳得胸口疼怎么办 怀孕偏左侧宫腔怎么办 晨起活动后咳嗽怎么办