如何使用压缩机Boost :: Iostreams过滤器作为Boost :: Log中的接收器 [英] How to use a compressor Boost::Iostreams filter as a sink in 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:
- 制作一个
shared_ptr
,其中包含您的filtering_ostream
和 - 确保延长输出文件流的生存期,直到关闭过滤流。
- Make a
shared_ptr
containing yourfiltering_ostream
, and - 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屋!