#include #include #include #include #include #include #include #include #include #include #include enum Level { A, B, C }; enum Group { G0, G1, G2 }; std::ostream& operator<<( std::ostream& stream, const Level& level ) { static const std::array strings = { "A", "B", "C" }; const auto levelIndex = static_cast(level)-static_cast(Level::A); assert(levelIndex >= 0); assert(levelIndex < strings.size()); return stream << strings[levelIndex]; } std::ostream& operator<<( std::ostream& stream, const Group& group ) { static const std::array strings = { "G0", "G1", "G2" }; const auto groupIndex = static_cast(group) - static_cast(Group::G0); assert(groupIndex >= 0); assert(groupIndex < strings.size()); return stream << strings[groupIndex]; } namespace { BOOST_LOG_ATTRIBUTE_KEYWORD(level, "Severity", Level) BOOST_LOG_ATTRIBUTE_KEYWORD(group, "Channel", Group) } namespace blog = boost::log; namespace expr = blog::expressions; void formatter( blog::record_view const& record, blog::formatting_ostream& stream ) { stream << "[" << record[level] << "]"; stream << "[" << record[group] << "]"; stream << " " << record[expr::smessage]; } typedef blog::sinks::asynchronous_sink< boost::log::sinks::text_ostream_backend > async_sink_t; auto async_sink0 = boost::make_shared(); auto async_sink1 = boost::make_shared(); void init() { async_sink0->locked_backend()->add_stream( boost::shared_ptr(&std::cout, boost::null_deleter{}) ); async_sink0->set_formatter(&formatter); blog::core::get()->add_sink(async_sink0); async_sink1->locked_backend()->add_stream( boost::make_shared("xxx.log") ); async_sink1->set_formatter(&formatter); blog::core::get()->add_sink(async_sink1); } void deinit() { blog::core::get()->remove_sink(async_sink0); // No logs going into sink async_sink0->stop(); // Stop the feed loop async_sink0->flush(); // All the waiting records are flushed to sink blog::core::get()->remove_sink(async_sink1); // No logs going into sink async_sink1->stop(); // Stop the feed loop async_sink1->flush(); // All the waiting records are flushed to sink } // Run this program several times. From time to time (timing issue?) you will see: // [][G0] Foo bar // [B][] Foo bar int main() { init(); blog::sources::severity_channel_logger_mt log; BOOST_LOG_CHANNEL_SEV(log, Group::G0, Level::B) << "Foo bar"; deinit(); std::cin.get(); return 0; }