Boost logo

Boost Users :

Subject: Re: [Boost-users] boost logging to file
From: Jarrett Chisholm (j.chisholm_at_[hidden])
Date: 2013-08-04 21:15:42


Thanks Leo - I didn't think about doing my own severity stuff, very
interesting.

It turns out, in my example, I needed to send the ' keywords::auto_flush
= true' parameter into the 'logging::add_file_log(..)' method. After
that, it worked fine - very weird.

Thanks for sending your example, I may pick some stuff out of it :)

Cheers

Jarrett

On 03/08/13 07:01 PM, Leo Carreon wrote:
> Hi Jarrett,
>
> I commiserate with your struggle in trying to get Boost.Log going.
> Sorry, I didn't try building your test program because in my opinion
> creating a logger class is not the way to go because doing so means
> you loose the flexibility of using stream-like syntax when logging.
> Instead all you really need is a function to initialize Boost.Log and
> then use Boost.Log's global logger mechanism.
>
> For example, here is my final test program when I was initially
> experimenting with Boost.Log:
>
> #include <iostream>
> #include <iomanip>
> #include <string>
> #include <boost/log/core.hpp>
> #include <boost/log/expressions.hpp>
> #include <boost/log/sources/global_logger_storage.hpp>
> #include <boost/log/sources/severity_logger.hpp>
> #include <boost/log/sources/record_ostream.hpp>
> #include <boost/log/attributes/clock.hpp>
> #include <boost/log/attributes/current_process_name.hpp>
> #include <boost/log/attributes/current_process_id.hpp>
> #include <boost/log/attributes/current_thread_id.hpp>
> #include <boost/log/support/date_time.hpp>
> #include <boost/log/utility/setup/file.hpp>
> #include <boost/log/utility/setup/formatter_parser.hpp>
> #include <boost/log/utility/setup/filter_parser.hpp>
>
> using namespace std;
>
> namespace logging = boost::log;
> namespace keywords = boost::log::keywords;
> namespace expr = boost::log::expressions;
> namespace attr = boost::log::attributes;
> namespace src = boost::log::sources;
>
> #define LFC1_LOG(logger, level) BOOST_LOG_SEV(logger, level) << "(" <<
> __FILE__ << ", " << __LINE__ << ") "
>
> #define LFC1_LOG_TRACE(logger) LFC1_LOG(logger, trace)
> #define LFC1_LOG_DEBUG(logger) LFC1_LOG(logger, debug)
> #define LFC1_LOG_INFO(logger) LFC1_LOG(logger, info)
> #define LFC1_LOG_WARNING(logger) LFC1_LOG(logger, warning)
> #define LFC1_LOG_ERROR(logger) LFC1_LOG(logger, error)
>
> static const auto RET_SUCCESS = 0;
> static const auto RET_FAIL = 1;
>
> enum ESeverityLevel
> {
> trace,
> debug,
> info,
> warning,
> error
> };
>
> BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", ESeverityLevel)
>
> static const char* gpStrings[] =
> {
> "trace",
> "debug",
> "info",
> "warning",
> "error"
> };
>
> ostream& operator<<(ostream& arStream, const ESeverityLevel& arLevel)
> {
> if (arStream.good())
> {
> if (static_cast<size_t>(arLevel) < sizeof(gpStrings) /
> sizeof(*gpStrings))
> {
> arStream << gpStrings[arLevel];
> }
> else
> {
> arStream << static_cast<int>(arLevel);
> }
> }
> return arStream;
> }
>
> istream& operator>>(istream& arStream, ESeverityLevel& arLevel)
> {
> if (arStream.good())
> {
> string vLevel;
> arStream >> vLevel;
> for (unsigned vI = 0; vI < sizeof(gpStrings) / sizeof(*gpStrings); ++vI)
> {
> if (vLevel == gpStrings[vI])
> {
> arLevel = static_cast<ESeverityLevel>(vI);
> }
> }
> }
> return arStream;
> }
>
> BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(SLogger,
> src::severity_logger<ESeverityLevel>)
>
> static void gvLoggingInit()
> {
> // Register a formatter and filter for severity level.
> logging::register_simple_formatter_factory<ESeverityLevel,
> char>("Severity");
> logging::register_simple_filter_factory<ESeverityLevel,
> char>("Severity");
>
> // Setup the default values for the log settings.
> string vFileName = "logs/log_%Y%m%d_%H%M%S_%3N.log";
> int vRotationSize = 1024;
> //string vTarget = "logs";
> //int vMaxSize = 10 * 1024;
> ESeverityLevel vSeverity = warning;
>
> // Add a file log with the given settings.
> logging::add_file_log
> (
> keywords::file_name = vFileName,
> keywords::rotation_size = vRotationSize,
> //keywords::target = vTarget,
> //keywords::max_size = vMaxSize,
> //keywords::scan_method = logging::sinks::file::scan_all,
> keywords::format = expr::stream
> << expr::format_date_time<boost::posix_time::ptime>("TimeStamp",
> "%Y-%m-%d %H:%M:%S.%f")
> << " ["
> << expr::attr<ESeverityLevel>("Severity")
> << "] "
> << expr::attr<string>("Process")
> << ":"
> << expr::attr<logging::process_id>("ProcessID")
> << ":"
> << expr::attr<logging::thread_id>("ThreadID")
> << " "
> << expr::message
> );
>
> // Add the logging attributes that we require.
> logging::core_ptr pCore = logging::core::get();
> pCore->add_global_attribute("TimeStamp", attr::local_clock());
> pCore->add_global_attribute("Process", attr::current_process_name());
> pCore->add_global_attribute("ProcessID", attr::current_process_id());
> pCore->add_global_attribute("ThreadID", attr::current_thread_id());
> pCore->set_filter(severity >= vSeverity);
> }
>
> int main()
> {
> try
> {
> gvLoggingInit();
>
> src::severity_logger<ESeverityLevel>& rLogger = SLogger::get();
>
> LFC1_LOG_TRACE(rLogger) << "A trace severity message";
> LFC1_LOG_DEBUG(rLogger) << "A debug severity message";
> LFC1_LOG_INFO(rLogger) << "An informational severity message";
> LFC1_LOG_WARNING(rLogger) << "A warning severity message";
> LFC1_LOG_ERROR(rLogger) << "An error severity message";
>
> LFC1_LOG_TRACE(rLogger) << "Another trace severity message";
> LFC1_LOG_DEBUG(rLogger) << "Another debug severity message";
> LFC1_LOG_INFO(rLogger) << "Another informational severity message";
> LFC1_LOG_WARNING(rLogger) << "Another warning severity message";
> LFC1_LOG_ERROR(rLogger) << "Another error severity message";
>
> return RET_SUCCESS;
> }
> catch (exception& crException)
> {
> cerr << crException.what() << endl;
> return RET_FAIL;
> }
> catch (...)
> {
> cerr << "Unknown exception" << endl;
> return RET_FAIL;
> }
> }
>
> My test program above also logs to a file, in fact it uses rotating
> log files. It also defines its own severity level, which requires two
> functions (operator<< and operator>>) to be defined and registered
> (really needed otherwise the severity level string will not appear in
> the logs) with Boost.Log. I also experimented with using a settings
> file which is not shown in the above code which I abandoned because I
> couldn't get the timestamp formatted the way I want it. You might
> also notice that I commented out the part to do with log file
> collectors because I encountered an issue with it. I also added my
> own attributes instead of adding the common attributes which I didn't
> all need.
>
> When I implemented the above into an actual application, I split it
> into 5 source files containing the following:
> 1. An include file which declares the severity level enumeration, the
> operator<< function and the operator>> function. This is included by
> the other 2 include files.
> 2. A source file which defines the operator<< and operator>>
> functions. Build and link this with your application.
> 3. An include file which declares the initialization function.
> Include this file in your application source file where you are going
> to invoke the initialization function.
> 4. A source file which defines the initialization function. Build and
> link this with your application.
> 5. An include file which defines your own logging macros and declares
> the global logger. Include this file in each of your application
> source files where you are going to perform logging.
>
> In my case, I added another 2 source files which declare and define my
> own settings class. Couldn't use Boost.Log's settings file for the
> reason I already mentioned above. These replace the default settings
> in my test program above. If you do this too, you either pass the
> name of the settings file to the initialization function or somehow
> the settings class must know where to look for the settings file.
>
> I hope this helps.
>
> Kind regards,
> Leo
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net