boost-log-库 使用经历

最近想整一个日志库,以前使用过log4cplus,看到了boost推出了1.54版本之后,就开始有了一个log库。这个log看了介绍,之后开始尝试去使用。主要的应用场景是让多个模块(so,dll)使用。场景是一个程序,多个模块,模块是单独的so,打印出来的日志,往同一个文件中输出。

最初的时候,编译的boost库是静态库,编译出来的,多是.a类型文件。当在一个日志模块中出示之后,到另一个模块中去使用,发现boost::log::core::get()获取出来的指针都不一样,但是看代码的时候,他明明说明是单例的,这让我困惑了很久。结果是明显的,boost::log::core::get()获取出来的指针不一样,在其他地方初始化的东西,肯定是没有效果的。是什么地方导致的,继续在代码中查找。看见了在在core.cpp中,core类使用implementation类,implementation继承lazy_singleton,这个类中,在获取单例的时候,使用一个很特殊的东西:__COUNTER__(windows)和__LINE__(LINUX),在不同的模块中,会是不同的值,生成不同的变量名,导致了boost::log::core::get()的值不一样。

活来查看boost的log文档,查找到一下内容:

If asynchronous logging is used in a multi-module application, one should decide carefully when to unload dynamically loaded modules that write logs. The library has many places where it may end up using resources that reside in the dynamically loaded module. Examples of such resources are virtual tables, string literals and functions. If any of these resources are still used by the library when the module in which they reside gets unloaded, the application will most likely crash. Strictly speaking, this problem exists with any sink type (and is not limited to sinks in the first place), but asynchronous sinks introduce an additional problem. One cannot tell which resources are used by the asynchronous sink because it works in a dedicated thread and uses buffered log records. There is no general solution for this issue. Users are advised to either avoid dynamic module unloading during the application‘s work time, or to avoid asynchronous logging. As an additional way to cope with the problem, one may try to shutdown all asynchronous sinks before unloading any modules, and after unloading re-create them. However, avoiding dynamic unloading is the only way to solve the problem completely.

大致说明了,在多模块的架构中,使用的时候,需要注意的地方。

以为多模块的事情解决了,准备使用配置文件,去加载log库,新问题出现了。看网上,大家都是新定义一个日志登记,之后,使用set_format去设置输出模式。但是在使用配置文件加载的使用(boost::log::init_from_stream),没法获取出sink方法(我个人也没有找到,如果有,请告诉我,谢谢),没有办法往日志中添加日志等级。后来改用log库自己的boost::log::trivial::severity_level,还是没有日志等级,这他妈神奇了!

经过查找,在stackoverflow中找到原因(经验:问题如果有,遇到的可能不是就自己,google还是有希望的),他们说这是一个bug(听到这句话,你也许会舒服一些)。

网址如下:http://stackoverflow.com/questions/18014335/boost-log-severity-logger-init-from-stream

解决的方式,就是重新定义format和filter,具体的函数如下:

boost::log::register_simple_formatter_factory<boost::log::trivial::severity_level, char>("Severity");
boost::log::register_simple_filter_factory<boost::log::trivial::severity_level, char>("Severity");
register_simple_formatter_factory 重新定义关于Severity的输出(out) (如果自定日志等级,需定义输入)
register_simple_filter_factory 定义关于Serverity的过滤(filter)(如果自定日志等级,需定义输入,值比较方法)

如果使用自己新的日志登记,最好直接参考traivaila.hpp 和 traivail.cpp的实现。具体怎么实现,在boost-log.pdf的帮助文档中,有详细的描述。标题:

Extending the library

Extending library settings support

Adding support for user-defined types to the formatter parser

Adding support for user-defined types to the filter parser

作者:wcl_hjs!

大家共同交流!

boost-log-库 使用经历

时间: 2024-10-25 03:46:18

boost-log-库 使用经历的相关文章

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(四)记录器

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

boost.log(三)接收器

设置接收器 BOOST_LOG_TRIVIAL不能提供足够的灵活性.例如,有时可能需要更复杂的逻辑来处理日志,而不是简单地将其打印在控制台上.为了定制这一点,你必须构造记录接收器,并在boost.log库core里面注册.这通常只需要你在应用程序启动的地方注册一次就够了. [注意]在前面的章节中我们没有初始化任何的接收器,因为boost.log库在没有初始化任何接收器的情况下会使用一个默认的接收器,这就是为什么我们能够在控制台中看到日志的输出结果.如果你设置了自定义的接收器,那么默认的接收器将会

boost.log(六)格式化

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

boost.log(五)属性

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

Boost Log

boost log支持以下配置宏,只列出一些常用的,如下表所示: Macro name Effect BOOST_LOG_DYN_LINK If defined in user code, the library will assume the binary is built as a dynamically loaded library (“dll” or “so”). Otherwise it is assumed that the library is built in static mo

boost.log(二)过滤

日志过滤 严重级别可以使日志信息更加翔实,但通常也会成为筛选器用来过滤日志记录的工具.在Log库的core里面可以通过设置全局过滤器很容易地做到日志过滤,就像下面一样: #include <iostream> #include <boost/log/core.hpp> #include <boost/log/trivial.hpp> #include <boost/log/expressions.hpp> void init() { boost::log::

Boost::Log::Tutorial::Setting up sinks

Setting up sinks 有时候,trivial(简单的)logging不能满足要求.例如,想要更多的处理日志处理,而不是简单地打印出来.为此,必须自己构建自定义的sinks,并且将它们注册到core中.这步操作通常在只在程序的开始执行一次. 注意 特别要提醒的是,在前面的章节中我们并没有初始化任何sinks,但trivial logging任然能够正常运行.这是因为,在用户没有设置任何sinks时,log库会使用一个默认的sink.这个默认的sink一般来说是将日志按照固定的格式打印到

Boost Log : Attributes

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