Search code examples
c++boostformatboost-log

boost log format single attribute with logging::init_from_stream


When I set up format params in code, to format date time output I can use something like this

logging::formatter simpleFormat(expr::format("%1% %2%") %
   expr::format_date_time<boost::posix_time::ptime>("TimeStamp", "%H:%M:%S") %
   expr::smessage
);

But when I initialize logger with a config file, I can specify format only in attributes position notation, not their format details.

so, this line in a boost log config file

Format="[%TimeStamp%]: %Message%"

produces output:

[2015-Feb-06 09:32:27.401496]: blah blah blah

I want to reduce timestamp to something like this

[06.02.2015 09:32:27]

How can it be described in boost log config file, ot it cant be done at all?


Solution

  • Preamble

    My answer is valid for boost 1.55 (haven't tested with latest one). And it was only tested with MSVC 2013 compiler.

    Answer

    Looks like you need custom formatter_factory for TimeStamp attribute to be able to specify it's format. This works for me:

    #include <fstream>
    #include "boost/shared_ptr.hpp"
    #include "boost/log/trivial.hpp"
    #include "boost/log/expressions.hpp"
    #include "boost/log/utility/setup.hpp"
    #include "boost/log/support/date_time.hpp"
    
    class timestamp_formatter_factory :
        public boost::log::basic_formatter_factory<char, boost::posix_time::ptime>
    {
        public:
            formatter_type create_formatter(boost::log::attribute_name const& name, args_map const& args)
            {
                args_map::const_iterator it = args.find("format");
                if (it != args.end())
                    return boost::log::expressions::stream << boost::log::expressions::format_date_time<boost::posix_time::ptime>(boost::log::expressions::attr<boost::posix_time::ptime>(name), it->second);
                else
                    return boost::log::expressions::stream << boost::log::expressions::attr<boost::posix_time::ptime>(name);
            }
    };
    
    int main()
    {
        // Initializing logging
        boost::log::register_formatter_factory("TimeStamp", boost::make_shared<timestamp_formatter_factory>());
        boost::log::add_common_attributes();
        std::ifstream file("settings.ini");
        boost::log::init_from_stream(file);
        // Testing
        BOOST_LOG_TRIVIAL(info) << "Test";
        return 0;
    }
    

    And now it your settings file you can specify format argument for TimeStamp attribute. Like this:

    [Sinks.ConsoleOut]
    Destination=Console
    AutoFlush=true
    Format="[%TimeStamp(format=\"%Y.%m.%d %H:%M:%S\")%]: %Message%"