【问题标题】:How to use a compressor Boost::Iostreams filter as a sink in Boost::Log如何在 Boost::Log 中使用压缩器 Boost::Iostreams 过滤器作为接收器
【发布时间】:2014-07-29 10:31:46
【问题描述】:

我正在尝试使用 boost::iostreams::gzip_compressor 即时压缩使用 Boost Log 库创建的日志文件。因此,当我调用BOOST_LOG() 时,输出会即时压缩。到目前为止,这是我尝试过的:

#include <fstream>
#include <iostream>

#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>

#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>

#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/sources/logger.hpp>

void init()
{
    // Construct the sink
    typedef boost::log::sinks::synchronous_sink< boost::log::sinks::text_ostream_backend > text_sink;
    boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();

    boost::shared_ptr< std::ofstream > file = boost::make_shared< std::ofstream >( 
            "sample.gz", std::ios_base::out | std::ios_base::binary );
    boost::iostreams::filtering_ostream out;
    out.push( boost::iostreams::gzip_compressor() );
    out.push( *(file.get()) );

    for( int i = 0; i < 10; i++ ) {
        out << "Hello world! " << i << std::endl; // compresses OK
    }

    sink->locked_backend()->add_stream( file );

    // Register the sink in the logging core
    boost::log::core::get()->add_sink( sink );
}

int main( )
{
    init();

    boost::log::sources::logger lg;
    for( int i = 0; i < 10; i++ ) 
        BOOST_LOG(lg) << "Bye world!" << std::endl; // Does not compress

    return 0;
}

我觉得我应该以某种方式要么 1)将整个filtering_ostream作为一个接收器,而不仅仅是file

2) 以某种方式推送记录器接收器而不是 filtering_ostream 中的 file

有人能指出我正确的方向吗?谢谢!

【问题讨论】:

    标签: c++ boost iostream boost-iostreams boost-log


    【解决方案1】:

    我认为您想将filtering_ostream 作为您的记录器流传递。你需要做两件事:

    1. 创建一个包含您的filtering_ostreamshared_ptr,然后
    2. 确保延长输出文件流的生命周期,直到过滤流关闭。

    您可以通过使用自定义shared_ptr 删除器来完成此操作。删除器是传递给shared_ptr 构造函数的可选函数对象,将调用它来释放指针。您可以将shared_ptrfile 存储在删除器中,以确保文件与流一样存在。在 C++11 中,您可以使用这样的 lambda:

    boost::shared_ptr<boost::iostreams::filtering_ostream> out(
       new boost::iostreams::filtering_ostream,
       [file](std::ostream *os) { delete os; });
    
    out->push(boost::iostreams::gzip_compressor());
    out->push(*file);
    
    sink->locked_backend()->add_stream(out);
    

    lambda 的[file] 部分将shared_ptr 保留到ofstream,直到调用删除器。

    如果你没有 C++11 编译器,你可以用一个普通的仿函数做同样的事情,比如(未编译和未经测试):

    struct MyDeleter {
       boost::shared_ptr<std::ofstream> file_;
    
       MyDeleter(const boost::shared_ptr<std::ofstream>& file)
          : file_(file) {
       }
    
       void operator()(std::ostream *os) {
          delete os;
       }
    };
    
    ...
    
    boost::shared_ptr<boost::iostreams::filtering_ostream> out(
       new boost::iostreams::filtering_ostream,
       MyDeleter(file));
    

    【讨论】:

    • 但是如果你这样做,你会失去旋转功能
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    相关资源
    最近更新 更多