Search code examples
c++loggingboostboost-logboost-logging

How to query boost::log severity?


I'm using trivial logging of boost::log library and I want to execute some code depending on currently set logger severity. This is needed for constructing of log message only if it will be outputted. But I cannot find the right way for querying severity. The code must be something like:

if (boost::log::trivial::severity <=
    boost::log::trivial::severity_level::trace)
{
  // construct log message
  BOOST_LOG_TRIVIAL(trace) << message;
}

In addition may be there is some way when I know that the message will be outputted to avoid double checking of severity and output it directly instead of using BOOST_LOG_TRIVIAL macro?


Solution

  • It doesn't work like that. You need to provide a filter function to boost::log::trivial as per the documentation:

    http://www.boost.org/doc/libs/1_61_0/libs/log/doc/html/log/tutorial/trivial_filtering.html

    void init()
    {
        logging::core::get()->set_filter
        (
            // here they've used a constant but you could use a global or
            // a function
            logging::trivial::severity >= logging::trivial::info
        );
    }
    
    int main(int, char*[])
    {
        init();
    
        BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
        BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
        BOOST_LOG_TRIVIAL(info) << "An informational severity message";
        BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
        BOOST_LOG_TRIVIAL(error) << "An error severity message";
        BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";
    
        return 0;
    }
    

    The object passed to logging::core::set_filter is of type boost::log::filter

    You could just as easily write:

    auto filt = logging::filter(logging::trivial::severity >= logging::trivial::info);
    logging::core::get()->set_filter(filt);
    

    filt is a lightweight function object whose job is to inspect the attributes sent to it and return whether or not all tests against those attributes return true. In this case there is only one test - logging::trivial::severity >= logging::trivial::info.

    It is the job of the logger to construct the attribute set and pass it to boost::log::core when it wants to emit something.

    The long and short of it is that you must track the logging level in your own variable. Here is one way:

    #include <iostream>
    #include <boost/log/core.hpp>
    #include <boost/log/trivial.hpp>
    #include <boost/log/expressions.hpp>
    
    namespace logging = boost::log;
    
    
    int main(int, char*[])
    {
        // track your own variable here
        logging::trivial::severity_level my_log_level = logging::trivial::trace;
    
        // with this filter
        auto filt = logging::filter(logging::trivial::severity >= my_log_level);
        logging::core::get()->set_filter(filt);
    
        BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
        BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
        BOOST_LOG_TRIVIAL(info) << "An informational severity message";
        BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
        BOOST_LOG_TRIVIAL(error) << "An error severity message";
        BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";
    
        // now you have control
        if (my_log_level <= logging::trivial::trace)
        {
            std::cout << "tracing\n";
        }
    
    
        return 0;
    }