1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
// boost1.67-1.67.0/libs/log/example/async_log/main.cpp
/*
* Copyright Andrey Semashev 2007 - 2015.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file main.cpp
* \author Andrey Semashev
* \date 30.08.2009
*
* \brief An example of asynchronous logging in multiple threads.
*/
#define BOOST_LOG_DYN_LINK 1
#include <stdexcept>
#include <string>
#include <iostream>
#include <fstream>
#include <functional>
#include <boost/ref.hpp>
#include <boost/bind.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/barrier.hpp>
#include <boost/log/common.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/sources/logger.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 expr = boost::log::expressions;
namespace keywords = boost::log::keywords;
using boost::shared_ptr;
enum
{
LOG_RECORDS_TO_WRITE = 10000,
THREAD_COUNT = 2
};
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(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::this_thread::get_id());
// Now, do some logging
for (unsigned int i = 0; i < LOG_RECORDS_TO_WRITE; ++i)
{
BOOST_LOG(test_lg::get()) << "Log record " << i;
}
}
int main(int argc, char* argv[])
{
try
{
// Open a rotating text file
shared_ptr< std::ostream > strm(new std::ofstream("test.log"));
if (!strm->good())
throw std::runtime_error("Failed to open a text log file");
// Create a text file sink
typedef sinks::text_ostream_backend backend_t;
typedef sinks::asynchronous_sink<
backend_t,
sinks::unbounded_ordering_queue<
logging::attribute_value_ordering< unsigned int, std::less< unsigned int > >
>
> sink_t;
shared_ptr< sink_t > sink(new sink_t(
boost::make_shared< backend_t >(),
// We'll apply record ordering to ensure that records from different threads go sequentially in the file
keywords::order = logging::make_attr_ordering("RecordID", std::less< unsigned int >())));
sink->locked_backend()->add_stream(strm);
sink->set_formatter
(
expr::format("%1%: [%2%] [%3%] - %4%")
% expr::attr< unsigned int >("RecordID")
% expr::attr< boost::posix_time::ptime >("TimeStamp")
% expr::attr< boost::thread::id >("ThreadID")
% expr::smessage
);
// Add it to the core
logging::core::get()->add_sink(sink);
// Add some attributes too
logging::core::get()->add_global_attribute("TimeStamp", attrs::local_clock());
logging::core::get()->add_global_attribute("RecordID", attrs::counter< unsigned int >());
// 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();
// Flush all buffered records
sink->stop();
sink->flush();
return 0;
}
catch (std::exception& e)
{
std::cout << "FAILURE: " << e.what() << std::endl;
return 1;
}
}
|