/*! * (C) 2007 Andrey Semashev * * Use, modification and distribution is subject to 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 11.11.2007 * * \brief An example of basic library usage. See the library tutorial for expanded * comments on this code. It may also be worthwhile reading the Wiki requirements page: * http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Boost.Logging */ #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS 1 #endif // _CRT_SECURE_NO_WARNINGS // #define BOOST_LOG_USE_CHAR // #define BOOST_ALL_DYN_LINK 1 // #define BOOST_LOG_DYN_LINK 1 #include #include #include #include #include #include #include #include #include #include // #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace logging = boost::log; namespace fmt = boost::log::formatters; namespace flt = boost::log::filters; namespace sinks = boost::log::sinks; namespace attrs = boost::log::attributes; namespace src = boost::log::sources; using boost::shared_ptr; // Here we define our application severity levels. enum severity_level { normal, notification, warning, error, critical }; int main(int argc, char* argv[]) { typedef sinks::synchronous_sink< sinks::text_ostream_backend > text_sink; shared_ptr< text_sink > pSink(new text_sink); { // The good thing about sink frontends is that they are provided out-of-box and // take away thread-safety burden from the sink backend implementors. Even if you // have to call a custom backend method, the frontend gives you a convenient way // to do it in a thread safe manner. All you need is to acquire a locking pointer // to the backend. text_sink::locked_backend_ptr pBackend = pSink->locked_backend(); // Now, as long as pBackend lives, you may work with the backend without // interference of other threads that might be trying to log. // Next we add streams to which logging records should be output shared_ptr< std::ostream > pStream(&std::clog, logging::empty_deleter()); pBackend->add_stream(pStream); // We can add more than one stream to the sink backend shared_ptr< std::ofstream > pStream2(new std::ofstream("sample.log")); assert(pStream2->is_open()); pBackend->add_stream(pStream2); } // Ok, we're ready to add the sink to the logging library logging::core::get()->add_sink(pSink); // Nice, huh? That's pretty much equivalent to writing the string to both the file // and the console. Now let's define the different way of formatting log records. // Each logging record may have a number of attributes in addition to the // message body itself. By setting up formatter we define which of them // will be written to log and in what way they will look there. pSink->locked_backend()->set_formatter(fmt::ostrm << fmt::attr("LineID") // First an attribute "LineID" is written to the log << " <" << fmt::attr("Severity") << "> [" << fmt::date_time< boost::posix_time::ptime >("TimeStamp", "%d.%m.%Y %H:%M:%S.%f") << "] " // then this delimiter separates it from the rest of the line << fmt::message()); // here goes the log record text // Now we're going to set up the attributes. // Remember that "LineID" attribute in the formatter? There is a counter // attribute in the library that increments or decrements the value each time // it is output. Let's create it with a starting value 1. shared_ptr< logging::attribute > pCounter(new attrs::counter< unsigned int >(1)); // Since we intend to count all logging records ever made by the application, // this attribute should clearly be global. logging::core::get()->add_global_attribute("LineID", pCounter); // And similarly add a time stamp shared_ptr< logging::attribute > pTimeStamp(new attrs::local_clock()); logging::core::get()->add_global_attribute("TimeStamp", pTimeStamp); logging::core::get()->set_filter(flt::attr< int >("Severity") >= warning); pSink->set_filter(flt::attr< int >("Severity") >= error); src::severity_logger slg; BOOST_LOG_SEV(slg, normal) << "A normal severity message, will not pass to the output (global filter)"; BOOST_LOG_SEV(slg, normal) << "A normal severity message, will not pass to the output (global filter)"; BOOST_LOG_SEV(slg, normal) << "A normal severity message, will not pass to the output (global filter)"; BOOST_LOG_SEV(slg, warning) << "An warning severity message, will not pass to the output (sink filter)"; BOOST_LOG_SEV(slg, warning) << "An warning severity message, will not pass to the output (sink filter)"; BOOST_LOG_SEV(slg, warning) << "An warning severity message, will not pass to the output (sink filter)"; BOOST_LOG_SEV(slg, error) << "An error severity message, will be printed"; BOOST_LOG_SEV(slg, error) << "An error severity message, will be printed"; BOOST_LOG_SEV(slg, error) << "An error severity message, will be printed"; return 0; }