如何使用压缩机Boost :: Iostreams过滤器作为Boost :: Log中的接收器 [英] How to use a compressor Boost::Iostreams filter as a sink in Boost::Log

查看:219
本文介绍了如何使用压缩机Boost :: Iostreams过滤器作为Boost :: Log中的接收器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to compress log files created using the Boost Log library instantaneously by utilizing boost::iostreams::gzip_compressor. So when I call BOOST_LOG(), output gets compressed on-the-fly. Here's what I tried so far:

#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)放在整个filter_ostream作为接收器,而不仅仅是 file

I get a feeling I should somehow either 1) put the whole filtering_ostream as a sink, not just file or

2)以某种方式推动记录器接收器而不是<$ c filtering_ostream 中的$ c> file 。

2) somehow push the logger sink instead of file in the filtering_ostream.

有人可以将我指向右边方向?谢谢!

Can someone point me to the right direction? Thanks!

推荐答案

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

I think you want to pass the filtering_ostream as your logger stream. You 'll need to do two things:


  1. 制作一个 shared_ptr ,其中包含您的 filtering_ostream

  2. 确保延长输出文件流的生存期,直到关闭过滤流。

  1. Make a shared_ptr containing your filtering_ostream, and
  2. Make sure the lifetime of the output file stream is extended until the filtering stream is closed.

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

You can accomplish this by using a custom shared_ptr deleter. The deleter is an optional function object passed to the shared_ptr constructor that will be called to free the pointer. You can store a shared_ptr to file in the deleter to make sure the file exists as long as the stream does. In C++11, you can do it with a lambda like this:

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 stream 直到调用删除程序。

The [file] part of the lambda keeps a shared_ptr to the ofstream until the deleter is called.

如果没有C ++ 11编译器,则可以使用普通仿函数执行相同的操作,例如(未经编译和未经测试):

If you don't have a C++11 compiler, you can do the same thing with an ordinary functor, something like (uncompiled and untested):

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

这篇关于如何使用压缩机Boost :: Iostreams过滤器作为Boost :: Log中的接收器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆