logger是用户接触最多的类

  • 可分为无保护和线程安全两类,线程安全的以_mt结尾
  • logger有窄字符和宽字符的,宽字符的以w开头,如wlogger_mt
  • logger类可复制,可创建的,可作为自定义类的成员
  • boost.log提供多种logger,参见网页

直接使用

如下即可:

#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;
}

全局logger

BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, src::logger_mt)
  • my_logger是用户自定义的logger名
  • src::logger_mt是logger类型
  • 可以注册多个全局对象

boost.log还提供其他的宏

注册全局logger后,可通过以下语句获取该对象:

src::logger_mt& lg = my_logger::get(); // my_logger是自己注册的全局对象名

写logger

写log的方法是通用的,如下:

logging::record rec = lg.open_record(); // lg是logger对象,logging record见后文
if (rec)
{logging::record_ostream strm(rec);strm << "Hello, World!";strm.flush();lg.push_record(boost::move(rec));
}
  • open_record相当于调用了logging core的filter (如本页最开头的severity),通过检测才会返回有效的logging::record对象
  • push_record在logging::record对象在信息填写完成后将消息推送出去

以上代码有更简单的替换版本:

BOOST_LOG(lg) << "Hello, World!";

配合attribute写log

attribute添加在logger上和record上可实现自定义的效果,下例中:

  • RemoteAddress添加到logger上,所有由这个logger发出的record都可使用```RemoteAddress``标签
  • Message添加在record上,那就只有这一条record有这个attribute
class network_connection
{src::logger m_logger;logging::attribute_set::iterator m_remote_addr;public:void on_connected(std::string const& remote_addr){// Put the remote address into the logger to automatically attach it// to every log record written through the loggerm_remote_addr = m_logger.add_attribute("RemoteAddress",attrs::constant< std::string >(remote_addr)).first;// The straightforward way of loggingif (logging::record rec = m_logger.open_record()){rec.attribute_values().insert("Message",attrs::make_attribute_value(std::string("Connection established")));m_logger.push_record(boost::move(rec));}}void on_disconnected(){// The simpler way of logging: the above "if" condition is wrapped into a neat macroBOOST_LOG(m_logger) << "Connection shut down";// Remove the attribute with the remote addressm_logger.remove_attribute(m_remote_addr);}void on_data_received(std::size_t size){// Put the size as an additional attribute// so it can be collected and accumulated later if needed.// The attribute will be attached only to this log record.BOOST_LOG(m_logger) << logging::add_value("ReceivedSize", size) << "Some data received";}void on_data_sent(std::size_t size){BOOST_LOG(m_logger) << logging::add_value("SentSize", size) << "Some data sent";}
};

Loggers 配合 severity

相关的类共有severity_loggerseverity_logger_mtwseverity_loggerwseverity_logger_mt4个。
这4个类都有Severity属性,在调用open_record函数时会先检查是否通过Severity属性检测,通过了就会返回record。
Severity属性说明:

  • int类型
  • 最好以0为起点,方便大小判断
  • 全局最好使用统一的级别
  • Severity可使用各种类型
// 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 constructionsrc::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!";
}

也可如下使用:

void default_severity()
{// The default severity can be specified in constructor.src::severity_logger< severity_level > error_lg(keywords::severity = error);BOOST_LOG(error_lg) << "An error level log record (by default)";// The explicitly specified level overrides the defaultBOOST_LOG_SEV(error_lg, warning) << "A warning level log record (overrode the default)";
}

不使用宏的情况:

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配合channel

相关的类共有channel_loggerchannel_logger_mtwchannel_loggerwchannel_logger_mt4类
这4个类都有Channel属性
这个类可用来区分不同的log
示例代码:

class network_connection
{src::channel_logger< > m_net, m_stat;logging::attribute_set::iterator m_net_remote_addr, m_stat_remote_addr;public:network_connection() :// We can dump network-related messages through this logger// and be able to filter them laterm_net(keywords::channel = "net"),// We also can separate statistic records in a different channel// in order to route them to a different sinkm_stat(keywords::channel = "stat"){}void on_connected(std::string const& remote_addr){// Add the remote address to both channelsattrs::constant< std::string > addr(remote_addr);m_net_remote_addr = m_net.add_attribute("RemoteAddress", addr).first;m_stat_remote_addr = m_stat.add_attribute("RemoteAddress", addr).first;// Put message to the "net" channelBOOST_LOG(m_net) << "Connection established";}void on_disconnected(){// Put message to the "net" channelBOOST_LOG(m_net) << "Connection shut down";// Remove the attribute with the remote addressm_net.remove_attribute(m_net_remote_addr);m_stat.remove_attribute(m_stat_remote_addr);}void on_data_received(std::size_t size){BOOST_LOG(m_stat) << logging::add_value("ReceivedSize", size) << "Some data received";}void on_data_sent(std::size_t size){BOOST_LOG(m_stat) << logging::add_value("SentSize", size) << "Some data sent";}
};

使用宏的简化版本

// Define a global logger
BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(my_logger, src::channel_logger_mt< >, (keywords::channel = "general"))class network_connection
{std::string m_remote_addr;public:void on_connected(std::string const& remote_addr){m_remote_addr = remote_addr;// Put message to the "net" channelBOOST_LOG_CHANNEL(my_logger::get(), "net")<< logging::add_value("RemoteAddress", m_remote_addr)<< "Connection established";}void on_disconnected(){// Put message to the "net" channelBOOST_LOG_CHANNEL(my_logger::get(), "net")<< logging::add_value("RemoteAddress", m_remote_addr)<< "Connection shut down";m_remote_addr.clear();}void on_data_received(std::size_t size){BOOST_LOG_CHANNEL(my_logger::get(), "stat")<< logging::add_value("RemoteAddress", m_remote_addr)<< logging::add_value("ReceivedSize", size)<< "Some data received";}void on_data_sent(std::size_t size){BOOST_LOG_CHANNEL(my_logger::get(), "stat")<< logging::add_value("RemoteAddress", m_remote_addr)<< logging::add_value("SentSize", size)<< "Some data sent";}
};

logger另有处理异常的版本和自定义混合类别的功能

再谈全局logger

使用全局logger,而在namespace内使用logger的原因:

  • c++没有规定namespace的初始化顺序
  • namespace的初始化并不是线程安全的
  • 在头文件的namespace中设定logger十分麻烦,因为还需要一个cpp文件配合
  • namespace内的变量在其内可访问,换句话说,模块B引用模块A,模块B内会创建同名的变量

使用全局logger可避免这些问题。创建全局logger:

BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, src::severity_logger_mt< >)

如果创建logger时需要传递参数,那么使用如下的宏,宏中的CTOR代表constructor,ARGS代表arguments

BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(my_logger,src::severity_channel_logger< >,(keywords::severity = error)(keywords::channel = "my_channel"))

如果前两个宏不能满足要求,还有第三个宏

BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(my_logger, src::severity_logger_mt)
{// Do something that needs to be done on logger initialization,// e.g. add a stop watch attribute.src::severity_logger_mt< > lg;lg.add_attribute("StopWatch", attrs::timer());// The initializing routine must return the logger instancereturn lg;
}

分开头文件和CPP文件设置全局logger

虽然上一节的宏可以设置全局logger,但在头文件中定义还是会有些麻烦。于是boost.log提供了在头文件和CPP文件中配合使用的宏:
BOOST_LOG_GLOBAL_LOGGER声明logger,类似于前文的BOOST_LOG_INLINE_GLOBAL_LOGGER*
BOOST_LOG_GLOBAL_LOGGER_INIT, BOOST_LOG_GLOBAL_LOGGER_DEFAULT
BOOST_LOG_GLOBAL_LOGGER_CTOR_ARGS使用类似于BOOST_LOG_INLINE_GLOBAL_LOGGER*,只不过要用在CPP文件中

// my_logger.h
// ===========BOOST_LOG_GLOBAL_LOGGER(my_logger, src::severity_logger_mt)// my_logger.cpp
// =============#include "my_logger.h"BOOST_LOG_GLOBAL_LOGGER_INIT(my_logger, src::severity_logger_mt)
{src::severity_logger_mt< > lg;lg.add_attribute("StopWatch", attrs::timer());return lg;
}

官方简单教程
官方logger高级教程

boost.log教程:loggers相关推荐

  1. Boost研究:Boost Log

    日志系统用于记录软件运行过程中的关键信息,是大型CAx软件系统的一个重要的组件. 本文拟对Boost.Log模块进行分析,旨在记录其技术要点. 注1:限于笔者研究水平,难免有理解不当,欢迎批评指正. ...

  2. boost log简介

    文章目录 前言 编译过程 一步步介绍boost-log boost-log的hello world boost-log的结构 boost-log的简单使用 按需定制日志库 - 略 前言 boost日志 ...

  3. boost::log模块测试样板,用于检查每个公共标头是否都是独立的并且没有任何缺失的 #includes

    boost::log模块测试样板,用于检查每个公共标头是否都是独立的并且没有任何缺失的 #includes 实现功能 C++实现代码 实现功能 boost::log模块测试样板,用于检查每个公共标头是 ...

  4. boost::log模块测试get_attributes()这个const方法可以获取线程模型内部的互斥锁

    boost::log模块测试get_attributes这个const方法可以获取线程模型内部的互斥锁 实现功能 C++实现代码 实现功能 boost::log模块测试get_attributes() ...

  5. boost::log模块测量转储二进制数据的性能

    boost::log模块测量转储二进制数据的性能 实现功能 C++实现代码 实现功能 boost::log模块测量转储二进制数据的性能 C++实现代码 #include <cstdlib> ...

  6. boost::log模块测量日志记录发射的性能

    boost::log模块测量日志记录发射的性能 实现功能 C++实现代码 实现功能 boost::log模块测量日志记录发射的性能 C++实现代码 #define BOOST_NO_DYN_LINK ...

  7. boost::log模块测试检查插入不会使容器中的现有元素无效

    boost::log模块测试检查插入不会使容器中的现有元素无效 实现功能 C++实现代码 实现功能 boost::log模块测试检查插入不会使容器中的现有元素无效 C++实现代码 #define BO ...

  8. boost::log::attributes::make_function用法的测试程序

    boost::log::attributes::make_function用法的测试程序 实现功能 C++实现代码 实现功能 boost::log::attributes::make_function ...

  9. boost::log::attribute_value_set用法的测试程序

    boost::log::attribute_value_set用法的测试程序 实现功能 C++实现代码 实现功能 boost::log::attribute_value_set用法的测试程序 C++实 ...

最新文章

  1. ABAP將數字輸出前面補0
  2. kafka 丢弃数据_20条关于Kafka集群应对高吞吐量的避坑指南
  3. 成功解决ValueError: `bins` must be positive, when an integer
  4. 随便选一张扑克牌_扑克牌魔术手法教学,简单易学的纸牌魔术,三分钟让你成为大师...
  5. leetcode41 --- firstMissingPositive
  6. 【软件工程】软件开发的本质
  7. 使用 ramda 解析 .yarnrc/.npmrc 配置文件的例子
  8. TCP/IP协议簇中ARP协议
  9. mysql的记录操作的日志文件_MySql 的操作日志 历史记录
  10. 护理在计算机的应用研究,计算机虚拟和模拟技术在护理实践教学中应用的研究...
  11. Scalable Web Architectures: Common Patterns and Approaches
  12. SqlServer批量插入测试数据
  13. PHP 三联截骨,Steel骨盆三联截骨联合手术治疗大龄儿童发育性髋关节脱位疗效观察...
  14. 怎样把图片转换成线条图?
  15. linux格式化命令,Linux怎么格式化磁盘啊?
  16. tcl电视linux软件升级,【高清范】TCL电视升级刷机常见问题大汇总!
  17. 记录win10突然卡死,只有鼠标能动,无法点击,大小写灯失效,只能强制关机
  18. 2020最新苹果企业级开发者账号续费流程
  19. WebDAV之葫芦儿·派盘+墨阅
  20. stata学习笔记|异方差问题

热门文章

  1. 美国虚拟主机安全吗?
  2. MAC系统如何更换管理员用户
  3. ArcGIS Desktop 10.2 安装与破解图文教程
  4. 博海拾贝--springcloud的组件及使用(3)服务网关 GateWay
  5. 228_QT_接227_统计学生三科成绩,用QBarSeries 树状图显示(显示到QChart,窗口中)QBarCategoryAxis、QValueAxis是不同的含义
  6. pandas中的read_csv参数详解
  7. 自学编程该如何入手?
  8. VFS - 代码生成器预览功能实现
  9. 机房用计算机,计算机机房为什么一定要使用防静电地板
  10. 职高计算机专业理论知识,浅论职高计算机专业教学