How to access boost log record_view attributes added via add_common_attributes()?

168 views Asked by At

So far, I've been formating the boost log using

void initLog() {
    boost::log::add_common_attributes();
    
    boost::log::add_console_log(std::cout, boost::log::keywords::auto_flush = true,
        boost::log::keywords::format = "[%TimeStamp%] [%ThreadID%] [%Severity%] %Message%");
}

int main() {
   initLog();
   BOOST_LOG_TRIVIAL(info)<<"My message";
}

which yields messages like
[2023-01-31 08:08:13.300149] [0x00007f66a048d000] [info] My message

Now, I'd like to replace this setup with a custom formatter like so:

void coloring_formatter(const boost::log::record_view& record, boost::log::formatting_ostream& stream) {
    auto severity = record[boost::log::trivial::severity];
    assert(severity);

    switch (severity.get()) {
    case boost::log::trivial::severity_level::trace:
        stream << "\e[97m";
        break;
    case boost::log::trivial::severity_level::debug:
        stream << "\e[34m";
        break;
    case boost::log::trivial::severity_level::info:
        stream << "\e[32m";
        break;
    case boost::log::trivial::severity_level::warning:
        stream << "\e[93m";
        break;
    case boost::log::trivial::severity_level::error:
        stream << "\e[91m";
        break;
    case boost::log::trivial::severity_level::fatal:
        stream << "\e[41m";
        break;
    }

    stream /* << boost::log::extract<boost::posix_time::ptime>("TimeStamp", record) << ": " */ //<< doesnt compile
           << boost::log::extract<unsigned int>("ThreadID", record) << ": " // << empty?
           << record[boost::log::expressions::message]; // << that's the only one working

    if (severity) {
        stream << "\033[0m";
    }
    
}

void initLogWithFormatter() {
    boost::log::add_common_attributes();
    
    auto consoleLog = boost::log::add_console_log(std::cout, boost::log::keywords::auto_flush = true);

    consoleLog->set_formatter(&coloring_formatter);
}

int main() {
   initLogWithFormatter();
   BOOST_LOG_TRIVIAL(info)<<"My message";
}

However, this does not access the attributes, like ThreadID, as I'd expected it to do. Instead, it simply outputs (in colour, at least)
: My message

How can I access the attributes added by boost::log::add_common_attributes() in the boost::log::record_view& in my custom formatter?

1

There are 1 answers

0
Dominic On

I was missing a header #include <boost/date_time/posix_time/posix_time_io.hpp>. Now, the formatter works using this implementation:

void coloring_formatter(const boost::log::record_view& record, boost::log::formatting_ostream& stream) {
    auto severity = record[boost::log::trivial::severity];
    assert(severity);

    switch (severity.get()) {
    case boost::log::trivial::severity_level::trace:
        stream << "\e[97m";
        break;
    case boost::log::trivial::severity_level::debug:
        stream << "\e[34m";
        break;
    case boost::log::trivial::severity_level::info:
        stream << "\e[32m";
        break;
    case boost::log::trivial::severity_level::warning:
        stream << "\e[93m";
        break;
    case boost::log::trivial::severity_level::error:
        stream << "\e[91m";
        break;
    case boost::log::trivial::severity_level::fatal:
        stream << "\e[41m";
        break;
    }

    stream << "[" << boost::log::extract<boost::posix_time::ptime>("TimeStamp", record) << "] " 
           << "[" << boost::log::extract<boost::log::attributes::current_thread_id::value_type>("ThreadID", record) << "] "
           << "[" << severity << "] " << record[boost::log::expressions::message];

    if (severity) {
        stream << "\033[0m";
    }
    
}

This yields the exact same output as initially configured - but with the formatter allowing for more granular control (and colours).