| 1 | #define WIN32_LEAN_AND_MEAN
|
|---|
| 2 | #include <windows.h>
|
|---|
| 3 |
|
|---|
| 4 | #include <string>
|
|---|
| 5 | #include <iostream>
|
|---|
| 6 | #include <fstream>
|
|---|
| 7 |
|
|---|
| 8 | #include <boost/log/attributes/clock.hpp>
|
|---|
| 9 | #include <boost/log/core.hpp>
|
|---|
| 10 | #include <boost/log/sinks/sync_frontend.hpp>
|
|---|
| 11 | #include <boost/log/sinks/text_ostream_backend.hpp>
|
|---|
| 12 | #include <boost/log/support/date_time.hpp>
|
|---|
| 13 | #include <boost/log/attributes/attribute.hpp>
|
|---|
| 14 | #include <boost/log/attributes/timer.hpp>
|
|---|
| 15 | #include <boost/log/trivial.hpp>
|
|---|
| 16 |
|
|---|
| 17 | namespace src = boost::log::sources;
|
|---|
| 18 | namespace sinks = boost::log::sinks;
|
|---|
| 19 | namespace attrs = boost::log::attributes;
|
|---|
| 20 |
|
|---|
| 21 | class PreciseTimer : public boost::log::attribute {
|
|---|
| 22 | public:
|
|---|
| 23 | typedef attrs::timer::value_type value_type;
|
|---|
| 24 |
|
|---|
| 25 | PreciseTimer() : boost::log::attribute(new PreciseTimerImpl) {}
|
|---|
| 26 |
|
|---|
| 27 | explicit PreciseTimer(boost::log::attributes::cast_source const& source) : boost::log::attribute(source.as< PreciseTimerImpl >())
|
|---|
| 28 | {
|
|---|
| 29 | }
|
|---|
| 30 |
|
|---|
| 31 | struct PreciseTimerImpl : public boost::log::attribute::impl {
|
|---|
| 32 | PreciseTimerImpl()
|
|---|
| 33 | {
|
|---|
| 34 | QueryPerformanceCounter(&m_startCounter);
|
|---|
| 35 | QueryPerformanceFrequency(&m_freq);
|
|---|
| 36 | }
|
|---|
| 37 | virtual boost::log::attribute_value get_value() {
|
|---|
| 38 | LARGE_INTEGER nowCounter;
|
|---|
| 39 | QueryPerformanceCounter(&nowCounter);
|
|---|
| 40 | double e = (nowCounter.QuadPart - m_startCounter.QuadPart) / (double) m_freq.QuadPart;
|
|---|
| 41 | return boost::log::attribute_value(new boost::log::attributes::attribute_value_impl< value_type >
|
|---|
| 42 | (boost::posix_time::microsec(static_cast<std::uint64_t>(e*1000000.0))));
|
|---|
| 43 | }
|
|---|
| 44 |
|
|---|
| 45 | LARGE_INTEGER m_freq, m_startCounter;
|
|---|
| 46 | };
|
|---|
| 47 | };
|
|---|
| 48 |
|
|---|
| 49 | BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp_id, "TimeStamp", attrs::local_clock::value_type)
|
|---|
| 50 | BOOST_LOG_ATTRIBUTE_KEYWORD(timer_id, "Timer", attrs::timer::value_type)
|
|---|
| 51 | BOOST_LOG_ATTRIBUTE_KEYWORD(timer_precise_id, "PreciseTimer", PreciseTimer::value_type)
|
|---|
| 52 |
|
|---|
| 53 | int protectedMain(int argc, char ** argv)
|
|---|
| 54 | {
|
|---|
| 55 | attrs::timer timerObject;
|
|---|
| 56 | boost::posix_time::ptime timerReference = boost::posix_time::microsec_clock::local_time();
|
|---|
| 57 |
|
|---|
| 58 | auto core = boost::log::core::get();
|
|---|
| 59 | core->add_global_attribute("TimeStamp", attrs::local_clock());
|
|---|
| 60 | core->add_global_attribute("Timer", timerObject);
|
|---|
| 61 | core->add_global_attribute("PreciseTimer", PreciseTimer());
|
|---|
| 62 |
|
|---|
| 63 | core->remove_all_sinks();
|
|---|
| 64 |
|
|---|
| 65 | auto sink = boost::make_shared< sinks::synchronous_sink< sinks::text_ostream_backend > >();
|
|---|
| 66 | boost::shared_ptr<std::ostream> out(new std::ofstream("output.log"));
|
|---|
| 67 | sink->locked_backend()->add_stream(out);
|
|---|
| 68 |
|
|---|
| 69 | sink->set_formatter([&timerReference] (boost::log::record_view const& rec, boost::log::formatting_ostream& strm)
|
|---|
| 70 | {
|
|---|
| 71 | auto & timerVal1 = rec[timer_id];
|
|---|
| 72 | auto & timerVal2 = rec[timer_precise_id];
|
|---|
| 73 | auto & clockVal = rec[timestamp_id];
|
|---|
| 74 | auto estimatedClock1 = timerReference + timerVal1.get();
|
|---|
| 75 | auto estimatedClock2 = timerReference + timerVal2.get();
|
|---|
| 76 |
|
|---|
| 77 | strm
|
|---|
| 78 | << "clock: " << boost::posix_time::to_iso_extended_string(clockVal.get()) << " "
|
|---|
| 79 | << "timer1: " << boost::posix_time::to_iso_extended_string(estimatedClock1) << " "
|
|---|
| 80 | << "diff1: " << (clockVal.get() - estimatedClock1).total_milliseconds() << "ms "
|
|---|
| 81 | << "timer2: " << boost::posix_time::to_iso_extended_string(estimatedClock2) << " "
|
|---|
| 82 | << "diff2: " << (clockVal.get() - estimatedClock2).total_milliseconds() << "ms "
|
|---|
| 83 | ;
|
|---|
| 84 | });
|
|---|
| 85 |
|
|---|
| 86 | core->add_sink(sink);
|
|---|
| 87 |
|
|---|
| 88 | boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time() +
|
|---|
| 89 | boost::posix_time::seconds(1);
|
|---|
| 90 |
|
|---|
| 91 | while(boost::posix_time::microsec_clock::local_time() < end){
|
|---|
| 92 | BOOST_LOG_TRIVIAL(info) << "Test";
|
|---|
| 93 | }
|
|---|
| 94 |
|
|---|
| 95 | core->remove_all_sinks();
|
|---|
| 96 | return 0;
|
|---|
| 97 | }
|
|---|
| 98 |
|
|---|
| 99 | int main(int argc, char ** argv) {
|
|---|
| 100 | try {
|
|---|
| 101 | return protectedMain(argc, argv);
|
|---|
| 102 | }
|
|---|
| 103 | catch(std::exception const & e){
|
|---|
| 104 | std::cerr << e.what() << std::endl;
|
|---|
| 105 | }
|
|---|
| 106 | return 0;
|
|---|
| 107 | }
|
|---|