0

Recently I started to play with boost.log, and bumped into an issue that if an unhanded exception is thrown no log messages are written to the log file. I am using rolling text files and auto-flash option is set on.

Here is the modified source from the samples:

#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;
    }
}

Source is compiled under Visual Studio 2008. boost.log compiled for boost 1.40.

Any help is highly appreciated.

Boaz Yaniv
  • 6,334
  • 21
  • 30
  • I tried your code, it worked for me. But you only expect log messages before exception happens, don't you? – JQ. May 03 '11 at 00:30

1 Answers1

2

Check to see if the log file is in the current working directory of the process, rather than the specified file collector target directory ("log" in your sample code). Additionally, you will probably want to specify a directory for the sink "file_name" pattern.

As "JQ" notes, don't expect to see any logging post-exception.

David Scherba
  • 668
  • 5
  • 6