我正在使用Boost.Log将各种数据集记录到不同的文件中。我想为某些文件启用auto_flush功能,但为其他文件禁用(以便在每个连续的日志语句中不插入换行符)。我无法在较大的项目中使用它。因此,我将问题简化为仅一个文件,但看来auto_flush仍无法禁用。这是一个最小示例的代码:

test.hpp:

#include <fstream>
#include <boost/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/log/core.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/trivial.hpp>

void init();


test.cpp:

#include "test.hpp"

void init() {
    // Initialize sink.
    typedef boost::log::sinks::synchronous_sink<boost::log::sinks::text_ostream_backend> text_sink;
    // Grab the Boost Log core.
    auto coreHandle = boost::log::core::get();
    // Add stream 1.
    boost::shared_ptr<text_sink> sink = boost::make_shared<text_sink>();
    sink->locked_backend()->add_stream(
            boost::make_shared<std::ofstream>("category1.log"));
    sink->locked_backend()->auto_flush(false);
    coreHandle->add_sink(sink);
}


main.cpp:

#include <iostream>
#include <string>
#include "test.hpp"

// Main entry point to program.
int main(int numArg, char const * const arguments[]) {

    double number1 = 42;

    init();

    BOOST_LOG_TRIVIAL(info) << "This message should go to category 1 log..." << number1;
    BOOST_LOG_TRIVIAL(info) << "This message should also go to category 1 log on the same line..." << number1;

    return EXIT_SUCCESS;
}


写入category1.log的输出显示,即使我在BOOST_LOG_TRIVIAL函数中将auto_flush显式设置为false,在两次对init()的调用之间也应用了换行符:

This message should go to category 1 log...42
This message should also go to category 1 log on the same line...42


我还使用BOOST_LOG_CHANNEL_SEV登录到多个文件,但是将auto_flush设置为false仍然无效。


如何禁用auto_flush,并让连续的日志语句打印到日志文件中的同一行?
是否可以将解决方案扩展到多个日志文件,以便可以对某些文件启用auto_flush,而对其他文件则不能启用?

最佳答案

如何禁用auto_flush,并让连续的日志语句打印到日志文件中的同一行?


首先,auto_flush与每个日志记录后的尾随换行没有关系。写入每个日志记录后,无论接收器是否包含换行符,它都会使接收器刷新其缓冲区。其次,只能根据每个接收器启用或禁用auto_flush。在text_ostream_backend的特定情况下,这意味着连接到接收器的所有流都将被刷新,或者都不刷新。第三,尾随换行符由接收器后端在内部输出,并且当前无法禁用此行为。

如果仅在选择日志记录后才要刷新日志文件,则最好的方法是使用属性来指示何时需要刷新。然后,您将必须创建自己的接收器后端,该后端将检查日志中记录的属性,该属性将对其进行处理并采取适当的措施。 here中描述了创建接收器。


  是否可以将解决方案扩展到多个日志文件,以便可以对某些文件启用auto_flush,而对其他文件则不能启用?


当然是。您必须为每个文件创建一个接收器,并在这些接收器中相应地设置auto_flush

更新2019-10-17:

关于尾随换行符的插入已经有了发展。在Boost 1.71中,在基于文本的接收器中,出现了一个选项,用于禁用自动尾随换行符插入。请参见接收器后端中的auto_newline_mode枚举和set_auto_newline_mode方法。

10-07 19:52
查看更多