记录器对象
在上个章节的接收器部分我们已经知道了boost.log库是如何存储日志的,现在是时候去尝试记录日志了。首先我们要创建一个记录器,这非常简单:
boost::log::sources::logger lg;
【注意】boost.log库在后台给记录器(logger)提供了写的功能,就如同BOOST_LOG_TRIVIAL 宏一样。
与接收器不同,记录器无须在任何地方注册,因为它们是直接与日志记录核心进行交互的。此外请注意boost.log库提供了两个版本的记录器: 线程安全的(logger_mt)非线程安全的(logger)。对非线程安全记录器来说,通过不同的记录器的实例在不同的线程上来写日志它是安全的,因此每个线程应该有一个单独的日志记录器。同时,线程安全的记录器可以在不同的线程间写日志,但是在抢夺线程的时候会导致速度下降。
全局记录器对象
如果你不想把一个记录器(logger)放置到你的类里面,boost.log库提供了一个宏来创建一个全局的记录器(logger):
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, boost::log::sources::logger_mt);
这里my_logger是一个用户自定义的名称,稍后将用于检索记录器(logger)实例和logger_mt对应的记录器(logger)类型。用户可以给boost.log库提供任何记录器(logger)类型的声明。然而,由于该记录器(logger)将会只有一个实例,你通常希望使用一个线程安全的全局记录器(logger)在多线程程序中工作。
接下来你就可以这样获取记录器(logger):
boost::log::sources::logger_mt& lg = my_logger::get();
lg将获取应用程序中记录器(logger)的唯一实例,而get()函数是线程安全的,无需额外的安全保护。
写入日志
不管你使用什么样的记录器(logger)(类成员或全局,线程安全与否),写一个记录到日志你都可以这样做:
#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log//sources/global_logger_storage.hpp>
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, boost::log::sources::logger_mt);
int main()
{
boost::log::sources::logger_mt& lg = my_logger::get();
boost::log::record rec = lg.open_record();
if (rec)
{
boost::log::record_ostream strm(rec);
strm << "Hello, World!";
strm.flush();
lg.push_record(boost::move(rec));
}
return 0;
}
这里的 open_record 函数的调用来确定是否有至少一个接收器来消费这条记录。日志记录的过滤就是在这一阶段进行的。如果记录被消耗,函数将返回一个有效的记录对象(record object),和一个可以填写记录消息的字符串。在那之后再调用push_record函数就可以完成记录处理了,结果如下:
当然上面的语法可以用一个宏来替换,boost.log库鼓励大家用宏而不是直接C++层面提供的接口,上面的日志可以这样写:
#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log//sources/global_logger_storage.hpp>
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, boost::log::sources::logger_mt);
int main()
{
boost::log::sources::logger_mt& lg = my_logger::get();
boost::log::record rec = lg.open_record();
if (rec)
{
BOOST_LOG(lg) << "Hello, World!";
}
return 0;
}