在C ++中增强日志记录和“类似对象”的日志记录行为

时间:2015-12-22 14:28:14

标签: c++ logging boost boost-log

我正在用C ++搜索一个日志库已经好几天了,但不知怎的,我对boost loggingPantheios等现有解决方案不太满意。最初我是Java开发人员。我想有一个带有记录器的日志记录库,它更像一个对象。我想做以下事情:

  1. 创建日志记录对象Logger(filepath, filename)
  2. 的实例
  3. 并使用log(serverity, message)方法记录文本文件中的不同消息
  4. 此功能的突出问题是我事先不知道这些日志对象中有多少将存在,或者这些文件是否具有相同的文件路径。也许我可以通过boost来处理这个问题,但是我没有在文档的“文本多文件后端”部分中获得example。特别是这个代码片段的例子是什么:

    Snippet 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")
        );
    

    Snippet 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记录库的应用程序范围的行为?这是由某种......全局变量完成的吗?
    5. 也许我的想法太天真了。有没有办法得到我在帖子开头提到的东西?

2 个答案:

答案 0 :(得分:1)

我认为你需要log4cxx日志库。它在日志文件中写入时确定日志级别 以下是您开始使用的参考资料。 http://www.yolinux.com/TUTORIALS/Log4cxx.html

答案 1 :(得分:1)

如果您是Boost.Log的新手,首先应该阅读库design,它与Java完全不同。尽管存在差异,但可以采用与log4j类似的方式配置库,this answer将有助于您入门。

现在,问题:

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

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

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

  • 可以将其添加到记录器manually。这是典型的,如果您创建一个用于处理请求的记录器(具有广泛的含义 - 应用程序中的“请求”意味着),并通过该记录器写入与请求处理相关的所有日志消息。
  • 可以将其作为scoped attribute添加到记录器中。如果您没有针对每个请求的专用记录器,但在某处使用通用记录器来编写与请求处理相关的日志,这将非常有用。
  • 可以将其作为范围属性添加到thread-specific attributes。如果请求处理涉及程序的不同部分中的多个记录器,这将有所帮助,但是在给定的时间点,仅一个线程(当前的线程)正在处理特定请求。其他线程可能正在处理其他请求并设置自己的特定于线程的属性 - 它们不会干扰。
  
      
  1. 使用boost可以将记录文件放在不同的路径中吗?
  2.   

当然。正如我所说,这可以通过向核心添加多个文件接收器来完成。就其本质而言,text_multifile_backend已经能够写入多个文件。

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

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

Loggers也有单线程和多线程版本,后者执行额外的锁定以保护其内部结构免受并发访问。但是,这种保护不会延伸到接收器上(即使你使用_mt记录器,接收器前端仍然需要同步线程)。

  
      
  1. init_logging()中的此代码是否会影响boost记录库的应用程序范围的行为?这是由某种......全局变量完成的吗?
  2.   

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