boost.log(三)接收器

设置接收器

BOOST_LOG_TRIVIAL不能提供足够的灵活性。例如,有时可能需要更复杂的逻辑来处理日志,而不是简单地将其打印在控制台上。为了定制这一点,你必须构造记录接收器,并在boost.log库core里面注册。这通常只需要你在应用程序启动的地方注册一次就够了。

【注意】在前面的章节中我们没有初始化任何的接收器,因为boost.log库在没有初始化任何接收器的情况下会使用一个默认的接收器,这就是为什么我们能够在控制台中看到日志的输出结果。如果你设置了自定义的接收器,那么默认的接收器将会失效,虽然你仍然可以使用BOOST_LOG_TRIVIAL来记录日志。

文件记录

下面将演示如何将记录写入到文件中:

  1. #include <iostream>
  2. #include <boost/log/core.hpp>
  3. #include <boost/log/trivial.hpp>
  4. #include <boost/log/expressions.hpp>
  5. #include <boost/log/utility/setup/file.hpp>
  6. void init()
  7. {
  8. boost::log::add_file_log("sample.log");
  9. boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::info);
  10. }

添加的代码片断是对 add_file_log 函数的调用。顾名思义,该函数初始化一个将日志记录存储到文本文件的接收器。该函数还接受了大量的自定义选项,例如文件大小限制。举个例子:

  1. #include <iostream>
  2. #include <boost/log/core.hpp>
  3. #include <boost/log/trivial.hpp>
  4. #include <boost/log/expressions.hpp>
  5. #include <boost/log/utility/setup/file.hpp>
  6. void init()
  7. {
  8. boost::log::add_file_log(
  9. boost::log::keywords::file_name = "sample_%N.log",
  10. boost::log::keywords::rotation_size = 10 * 1024 * 1024,
  11. boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0),
  12. boost::log::keywords::format = "[%TimeStamp%]: %Message%"
  13. );
  14. boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::info);
  15. }

查看完整的代码

下面介绍一下add_file_log函数的参数列表:

  • 参数1:文件名模板
  • 参数2:超过此文件大小自动建立新文件
  • 参数3:超过此时间自动建立新文件
  • 参数4:日志记录格式

【注意】你可以注册多个接收器,每个接收器将接收并处理日志记录。

深入接收器

在最简单的形式中,对以上代码中的 add_file_log 函数的调用是几乎等同于此:

  1. #include <fstream>
  2. #include <boost/log/core.hpp>
  3. #include <boost/smart_ptr.hpp>
  4. #include <boost/log/trivial.hpp>
  5. #include <boost/log/sinks/sync_frontend.hpp>
  6. #include <boost/log/sources/record_ostream.hpp>
  7. #include <boost/log/sinks/text_ostream_backend.hpp>
  8. void init()
  9. {
  10. // 构造接收器
  11. typedef boost::log::sinks::synchronous_sink<boost::log::sinks::text_ostream_backend > text_sink;
  12. boost::shared_ptr<text_sink> sink = boost::make_shared<text_sink>();
  13. // 添加一个流写入日志
  14. sink->locked_backend()->add_stream(boost::make_shared< std::ofstream >("sample.log"));
  15. // 注册接收器
  16. boost::log::core::get()->add_sink(sink);
  17. }

查看完整的代码

你可能已经注意到了接收器是由两个类组成:frontend  和 backend  。 frontend (上述片段中的boost::log::sinks::synchronous_sink模板类) 负责所有接收器常见的各种任务,如线程同步模型、 过滤和基于文本的接收器,格式。 backend (上述片段中的boost::log::sinks::text_ostream_backend) 实现接收器所有具体的功能,如在这种情况下写入一个文件。log库提供大量的 frontend  和 backend  ,它们是现成的,可以彼此一起组合使用。

boost::log::sinks::synchronous_sink 表示接收器是同步的,它允许多个线程在争用的情况下写入日志。这意味着后端 boost::log::sinks::text_ostream_backend不必担心多线程问题。

boost::log::sinks::text_ostream_backend 类写入格式化日志记录到 STL 兼容的流。上面我们使用了一个文件流,但是我们也可以使用一个任何类型的流。例如,添加到控制台输出:

  1. #include <boost/log/core.hpp>
  2. #include <boost/smart_ptr.hpp>
  3. #include <boost/log/trivial.hpp>
  4. #include <boost/core/null_deleter.hpp>
  5. #include <boost/log/sinks/sync_frontend.hpp>
  6. #include <boost/log/sinks/text_ostream_backend.hpp>
  7. void init()
  8. {
  9. // 构造接收器
  10. typedef boost::log::sinks::synchronous_sink<boost::log::sinks::text_ostream_backend > text_sink;
  11. boost::shared_ptr<text_sink> sink = boost::make_shared<text_sink>();
  12. // 添加一个流写入日志
  13. boost::shared_ptr< std::ostream > stream(&std::clog, boost::null_deleter());
  14. sink->locked_backend()->add_stream(stream);
  15. // 注册接收器
  16. boost::log::core::get()->add_sink(sink);
  17. }

boost::log::sinks::text_ostream_backend支持添加多个流,这这种情况下,其输出将被赋值到所有加入的流之中。所有它可以同时在控制台或者是文件中输出结果。如果开启了过滤,那么boost.log库只会在记录没有被过滤掉的日志时才会产生开销。

【注意】注册几个不同接收器与多个目标流注册到一个接收器的区别。前者允许独立定制每个接收器的输出,后者如果不需要这样的定制将工作相当快,此特性是特定于这个特定的 backend  。

boost.log库通过提供一系列的 backend  ,来提供不同的日志处理的逻辑。例如,通过指定系统日志的backend  可以网络日志记录把发送到日志服务器,或通过设置Windows NT事件日志的backend  可以使用Windows应用程序的运行时监控工具,使应用程序运行时发出的日志记录。

最后要说的是调用成员函数 locked_backend() 来访问接收器backend 。它被所有接收器的frontend 提供,用于获取到backend 的线程安全访问。此函数返回一个backend 的智能指针,并且它存在一个backend 锁 (这意味着如果另一个线程此时将日志记录传递到接收器,它将被阻塞直到释放backend 后)。唯一的例外是 unlocked_sink类型的frontend 根本不同步,只是返回一个解锁的backend指针。

关于接收器的更多信息:

Sink frontends:http://www.boost.org/doc/libs/1_58_0/libs/log/doc/html/log/detailed/sink_frontends.html

Sink backends:http://www.boost.org/doc/libs/1_58_0/libs/log/doc/html/log/detailed/sink_backends.html

时间: 2024-08-29 07:01:09

boost.log(三)接收器的相关文章

boost.log(五)属性

在前面几节中我们提到属性和属性值好几次.在这节我们会学习如何使用属性,以添加更多的数据到日志记录. 每条日志记录可以附加多个已命名的属性值,属性可以代表日志记录产生时任何与程序运行相关的数据信息.如代码位置.执行模块名称.当前数据和时间以及程序运行相关的任何数据信息.属性可以表现为一个值生成器,在这种情况下,将用于返回它参与的每个不同日志记录所生成的值.一旦属性生成值,就可以把这个值用于过滤器,格式化器和接收器.但是使用该属性值你必须知道它的名称和类型.boost.log库中实现了常用的属性,你

Boost Log 基本用法

Boost Log 基本用法 flyfish 2014-11-5 根据boost提供的代码示例,学习Boost Log 的基本用法 前提 boost版本boost_1_56_0 示例代码文件夹 boost_1_56_0\libs\log\example\basic_usage 使用的单词很形象,整个过程就像流水一样 假设要输出的日志比作水 水                     (Hello, World!) 水槽                 (sink) 流向哪里        (co

boost.log(九) 配置文件

前面几节中描述了Boost.Log 的基础知识,对Boost.Log 库的操作我们都是在C++代码中进行中,这样就会有一些不便的地方.比如说我们想要更改一下输出格式或者过滤条件,都必须对C++代码进行更改,并且还得编译一次(感觉编译时间还有点长).其实Boost.Log 里面已经为这个问题提供了一种解决方案,就是通过配置文件来初始化Boost.Log 库,C++这边的代码也比较简单,就是这样的: std::ifstream settings("settings.txt"); if (!

boost.log(八)宽字符记录

宽字符记录 Boost.Log支持包含本地字符集字符串的日志记录.基本上有两种方式做这件事.在 UNIX 系统上通常使用一些多字节字符编码 (例如 UTF-8) 用来表示本地字符.在这种情况下,Boost.Log库可以直接以纯 ASCII 的方式记录而不需要其它额外的设置. 在Windows 上常见的做法是使用宽字符串来表示本地字符串.此外大多数系统 API 也是使用的宽字符,这需要特定于 Windows 的接收器也支持宽字符.另一方面,通用的接收器,例如 TextFile,是面向字节的,你写入

boost.log(七)再谈过滤

再谈过滤 我们已经在前面的章节接触过滤,但只是浅尝辄止.我们现在能够添加日志记录并设置接收器的属性,我们需要建立复杂的过滤功能.让我们看下这个例子: #include <string> #include <fstream> #include <iomanip> #include <boost/log/core.hpp> #include <boost/smart_ptr.hpp> #include <boost/log/sinks.hpp&

boost.log(四)记录器

记录器对象 在上个章节的接收器部分我们已经知道了boost.log库是如何存储日志的,现在是时候去尝试记录日志了.首先我们要创建一个记录器,这非常简单: boost::log::sources::logger lg; [注意]boost.log库在后台给记录器(logger)提供了写的功能,就如同BOOST_LOG_TRIVIAL 宏一样. 与接收器不同,记录器无须在任何地方注册,因为它们是直接与日志记录核心进行交互的.此外请注意boost.log库提供了两个版本的记录器: 线程安全的(logg

boost.log(六)格式化

如果你尝试运行上一节中的例子,你会发现只有日志记录消息(没有时间戳等属性信息)会被写入到文件.这是因为boost.log库没有设置格式化.即使你添加了属性到boost.log的core或者是记录器中,记录值也不会被输出,除非你指定了这些值的格式. 回到在前面节教程的一个例子: #include <iostream> #include <boost/log/utility/setup/file.hpp> #include <boost/log/sinks/basic_sink_

Boost Log : Attributes

Adding more information to log: Attributes 在前面的章节中,我们多次提到了属性和属性值.在这里,我们将发现如何使用属性向日志记录添加更多的数据. 每一个日志记录都可以包含许多命名的属性值.属性可以表示任何关于日志记录发生的条件的基本信息,比如代码中的位置,可执行的模块名,当前日期和时间,或者任何与您的特定应用程序和执行环境相关的数据.一个属性可以表现为一个值生成器,在这种情况下,它会为它所涉及的每个日志记录返回一个不同的值.只要属性生成该值,后者就会独立

boost.log要点笔记

常用简写: namespace logging = boost::log; namespace src = boost::log::sources; namespace expr = boost::log::expressions; namespace sinks = boost::log::sinks; namespace attrs = boost::log::attributes; namespace keywords = boost::log::keywords; 要点: 结构图要牢记在