boost.log教程:loggers
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_logger
、severity_logger_mt
、 wseverity_logger
和wseverity_logger_mt
4个。
这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_logger
、channel_logger_mt
、 wchannel_logger
和wchannel_logger_mt
4类
这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相关推荐
- Boost研究:Boost Log
日志系统用于记录软件运行过程中的关键信息,是大型CAx软件系统的一个重要的组件. 本文拟对Boost.Log模块进行分析,旨在记录其技术要点. 注1:限于笔者研究水平,难免有理解不当,欢迎批评指正. ...
- boost log简介
文章目录 前言 编译过程 一步步介绍boost-log boost-log的hello world boost-log的结构 boost-log的简单使用 按需定制日志库 - 略 前言 boost日志 ...
- boost::log模块测试样板,用于检查每个公共标头是否都是独立的并且没有任何缺失的 #includes
boost::log模块测试样板,用于检查每个公共标头是否都是独立的并且没有任何缺失的 #includes 实现功能 C++实现代码 实现功能 boost::log模块测试样板,用于检查每个公共标头是 ...
- boost::log模块测试get_attributes()这个const方法可以获取线程模型内部的互斥锁
boost::log模块测试get_attributes这个const方法可以获取线程模型内部的互斥锁 实现功能 C++实现代码 实现功能 boost::log模块测试get_attributes() ...
- boost::log模块测量转储二进制数据的性能
boost::log模块测量转储二进制数据的性能 实现功能 C++实现代码 实现功能 boost::log模块测量转储二进制数据的性能 C++实现代码 #include <cstdlib> ...
- boost::log模块测量日志记录发射的性能
boost::log模块测量日志记录发射的性能 实现功能 C++实现代码 实现功能 boost::log模块测量日志记录发射的性能 C++实现代码 #define BOOST_NO_DYN_LINK ...
- boost::log模块测试检查插入不会使容器中的现有元素无效
boost::log模块测试检查插入不会使容器中的现有元素无效 实现功能 C++实现代码 实现功能 boost::log模块测试检查插入不会使容器中的现有元素无效 C++实现代码 #define BO ...
- boost::log::attributes::make_function用法的测试程序
boost::log::attributes::make_function用法的测试程序 实现功能 C++实现代码 实现功能 boost::log::attributes::make_function ...
- boost::log::attribute_value_set用法的测试程序
boost::log::attribute_value_set用法的测试程序 实现功能 C++实现代码 实现功能 boost::log::attribute_value_set用法的测试程序 C++实 ...
最新文章
- ABAP將數字輸出前面補0
- kafka 丢弃数据_20条关于Kafka集群应对高吞吐量的避坑指南
- 成功解决ValueError: `bins` must be positive, when an integer
- 随便选一张扑克牌_扑克牌魔术手法教学,简单易学的纸牌魔术,三分钟让你成为大师...
- leetcode41 --- firstMissingPositive
- 【软件工程】软件开发的本质
- 使用 ramda 解析 .yarnrc/.npmrc 配置文件的例子
- TCP/IP协议簇中ARP协议
- mysql的记录操作的日志文件_MySql 的操作日志 历史记录
- 护理在计算机的应用研究,计算机虚拟和模拟技术在护理实践教学中应用的研究...
- Scalable Web Architectures: Common Patterns and Approaches
- SqlServer批量插入测试数据
- PHP 三联截骨,Steel骨盆三联截骨联合手术治疗大龄儿童发育性髋关节脱位疗效观察...
- 怎样把图片转换成线条图?
- linux格式化命令,Linux怎么格式化磁盘啊?
- tcl电视linux软件升级,【高清范】TCL电视升级刷机常见问题大汇总!
- 记录win10突然卡死,只有鼠标能动,无法点击,大小写灯失效,只能强制关机
- 2020最新苹果企业级开发者账号续费流程
- WebDAV之葫芦儿·派盘+墨阅
- stata学习笔记|异方差问题
热门文章
- 美国虚拟主机安全吗?
- MAC系统如何更换管理员用户
- ArcGIS Desktop 10.2 安装与破解图文教程
- 博海拾贝--springcloud的组件及使用(3)服务网关 GateWay
- 228_QT_接227_统计学生三科成绩,用QBarSeries 树状图显示(显示到QChart,窗口中)QBarCategoryAxis、QValueAxis是不同的含义
- pandas中的read_csv参数详解
- 自学编程该如何入手?
- VFS - 代码生成器预览功能实现
- 机房用计算机,计算机机房为什么一定要使用防静电地板
- 职高计算机专业理论知识,浅论职高计算机专业教学