提升C++中的日志记录和"类对象"日志记录行为

Boost Logging and 'Object-like' Logging Behaviour in C++

本文关键字:日志 记录 对象 C++ 提升      更新时间:2023-10-16

我在C++中搜索日志库已经好几天了,但不知何故,我对现有的解决方案(如boost logging或Pantheios)不太满意。最初我是一名Java开发人员。我想有一个日志库,带有一个行为更像对象的记录器。我想做以下事情:

  1. 创建日志记录对象Logger(filepath, filename)的实例
  2. 并使用log(serverity, message)方法在文本文件中记录不同的消息

这些功能的突出问题是,我事先不知道这些日志记录对象中有多少个,也不知道这些文件是否具有相同的文件路径。也许我可以用boost来处理这个问题,但我在文档的"文本多文件后端"部分没有得到这个例子。特别是这个例子中的代码片段会做什么:

片段1。

 // Set up the file naming pattern
    backend->set_file_name_composer
    (
        sinks::file::as_file_name_composer(expr::stream << "logs/" << expr::attr< std::string >("RequestID") << ".log")
    );

片段2。

 // Set the formatter
    sink->set_formatter
    (
        expr::stream
            << "[RequestID: " << expr::attr< std::string >("RequestID")
            << "] " << expr::smessage
    );

这个代码在我的脑海中提出了4个问题:

  1. 这是否意味着我只需要设置属性RequestID,然后记录器就会决定将消息放在哪个文件中?我该怎么做
  2. 使用boost是否可以将日志文件保存在不同的路径中
  3. 如果不同的线程访问同一个文件会发生什么
  4. init_logging()中的这段代码会影响boost日志记录库在应用程序范围内的行为吗?这是由某种。。。全局变量

也许我的想法太天真了。有没有一种方法可以得到我在帖子开头提到的东西?

如果你是Boost.Log的新手,你应该先了解一下库的设计,它与Java有很大的不同。尽管存在差异,但可以以与log4j类似的方式配置库,这个答案将有助于您入门。

现在,回答您的问题:

  1. 这是否意味着我只需要设置属性RequestID,然后记录器就会决定将消息放在哪个文件中?我该怎么做

text_multifile_backend的特定情况下,接收器将决定将每个日志记录写入哪个文件。set_file_name_composer调用设置了一个组成日志文件名的函数对象,正如您所看到的,它涉及RequestID属性。当然,您可以使用任何您喜欢的属性,包括通道。您还应该知道,text_multifile_backend并不是实现您想要的目标的唯一方法(也可能不是最有效的方法)。如果不同日志文件的数量有限,通常最好添加几个文本文件接收器,每个文件一个,并设置筛选,以便每个接收器接收自己的日志记录。我在上面链接的答案中描述了这种方法。

关于添加属性,根据用例和您要将其添加到的属性集,有不同的方法。在通道的情况下,此属性由记录器自动提供,您只需使用通道名称创建记录器,通过该记录器创建的每个日志记录都将其附加为属性。您所指向的示例中的RequestID属性可以以任何可能的方式添加。以下是几个常见的例子:

  • 它可以手动添加到记录器中。如果您创建了一个用于处理请求的记录器(广义上讲,无论"请求"在您的应用程序中是什么意思),并通过该记录器写入与请求处理相关的所有日志消息,则这是典型的情况
  • 它可以作为作用域属性添加到记录器中。如果您没有针对每个请求的专用记录器,但在某个地方有一个通用记录器,用于编写与请求处理相关的日志,那么这将非常有用
  • 它可以作为作用域属性添加到线程特定的属性中。如果请求处理涉及程序不同部分的多个记录器,但在给定的时间点只有一个线程(当前线程)在处理特定请求,这将有所帮助。其他线程可能正在处理其他请求,并设置自己的线程特定属性——它们不会干扰
  1. 使用boost是否可以将日志文件保存在不同的路径中

当然。正如我所说,这可以通过向核心添加多个文件接收器来实现。从本质上讲,text_multifile_backend已经能够写入多个文件。

  1. 如果不同的线程访问同一个文件会发生什么

Boost.Log支持多线程。在接收器级别上,接收器前端实现线程同步。例如,synchronous_sink前端将阻止竞争线程同时写入单个文件。日志记录可以同时写入不同的接收器。

记录器也有单线程和多线程版本,后者进行额外的锁定以保护其内部结构免受并发访问。然而,这种保护并没有在接收器上扩展(即,即使您使用_mt记录器,接收器前端仍然必须同步线程)。

  1. init_logging()中的这段代码会影响boost日志记录库在应用程序范围内的行为吗?这是由某种。。。全局变量

Boost.Log中有很多单身汉,是的。最值得注意的是,日志核心,在其中注册所有接收器以及全局和线程特定的属性。添加一个新的接收器将对整个应用程序产生影响,因为所有记录器的记录都将开始进入该接收器(这就是为什么在将接收器添加到核心之前通常应该配置它)。记录器本身与接收器无关,日志记录最终出现在哪个接收器中仅由筛选器定义。但正如我所提到的,在属性和过滤器的帮助下,可以将记录器和接收器关联起来,并以相关的方式管理它们。您必须编写一个包装类,提供您所描述的接口以及Boost。日志记录器创建并配置相应的接收器。

我认为您需要log4cxx日志库。当您将其写入日志文件时,它会确定日志级别
这是你入门的参考资料。http://www.yolinux.com/TUTORIALS/Log4cxx.html