最近我开始玩 boost.log,遇到了一个问题,即如果抛出一个未经处理的异常,则不会将日志消息写入日志文件。我正在使用滚动文本文件并设置了自动闪光选项。
以下是来自示例的修改源:
#include <stdexcept>
#include <string>
#include <iostream>
#include <fstream>
#include <functional>
#include <boost/ref.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/barrier.hpp>
#include <boost/log/common.hpp>
#include <boost/log/filters.hpp>
#include <boost/log/formatters.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/utility/empty_deleter.hpp>
#include <boost/log/utility/record_ordering.hpp>
namespace logging = boost::log;
namespace attrs = boost::log::attributes;
namespace src = boost::log::sources;
namespace sinks = boost::log::sinks;
namespace fmt = boost::log::formatters;
namespace keywords = boost::log::keywords;
using boost::shared_ptr;
using namespace boost::gregorian;
enum
{
LOG_RECORDS_TO_WRITE = 100,
LOG_RECORDS_TO_WRITE_BEFORE_EXCEPTION = 10,
THREAD_COUNT = 10
};
BOOST_LOG_DECLARE_GLOBAL_LOGGER(test_lg, src::logger_mt)
//! This function is executed in multiple threads
void thread_fun(boost::barrier& bar)
{
// Wait until all threads are created
bar.wait();
// Here we go. First, identify the thread.
BOOST_LOG_SCOPED_THREAD_TAG("ThreadID", boost::thread::id, boost::this_thread::get_id());
// Now, do some logging
for (unsigned int i = 0; i < LOG_RECORDS_TO_WRITE; ++i)
{
BOOST_LOG(get_test_lg()) << "Log record " << i;
if(i > LOG_RECORDS_TO_WRITE_BEFORE_EXCEPTION)
{
BOOST_THROW_EXCEPTION(std::exception("unhandled exception"));
}
}
}
int main(int argc, char* argv[])
{
try
{
typedef sinks::synchronous_sink< sinks::text_file_backend > file_sink;
shared_ptr< file_sink > sink(new file_sink(
keywords::file_name = L"%Y%m%d_%H%M%S_%5N.log", // file name pattern
keywords::rotation_size = 10 * 1024 * 1024, // rotation size, in characters
keywords::auto_flush = true // make each log record flushed to the file
));
// Set up where the rotated files will be stored
sink->locked_backend()->set_file_collector(sinks::file::make_collector(
keywords::target = "log" // where to store rotated files
));
// Upon restart, scan the target directory for files matching the file_name pattern
sink->locked_backend()->scan_for_files();
sink->locked_backend()->set_formatter(
fmt::format("%1%: [%2%] [%3%] - %4%")
% fmt::attr< unsigned int >("Line #")
% fmt::date_time< boost::posix_time::ptime >("TimeStamp")
% fmt::attr< boost::thread::id >("ThreadID")
% fmt::message()
);
// Add it to the core
logging::core::get()->add_sink(sink);
// Add some attributes too
shared_ptr< logging::attribute > attr(new attrs::local_clock);
logging::core::get()->add_global_attribute("TimeStamp", attr);
attr.reset(new attrs::counter< unsigned int >);
logging::core::get()->add_global_attribute("Line #", attr);
// Create logging threads
boost::barrier bar(THREAD_COUNT);
boost::thread_group threads;
for (unsigned int i = 0; i < THREAD_COUNT; ++i)
threads.create_thread(boost::bind(&thread_fun, boost::ref(bar)));
// Wait until all action ends
threads.join_all();
return 0;
}
catch (std::exception& e)
{
std::cout << "FAILURE: " << e.what() << std::endl;
return 1;
}
}
源代码在 Visual Studio 2008 下编译。 boost.log 为 boost 1.40 编译。
非常感谢任何帮助。