Search code examples
c++boostboost-log

Unable to print other levels via BOOST_LOG_SEV


I'm trying to use Boost.Log but when I use:

BOOST_LOG_SEV(slg, level)//Doesn't matter the level here

even if manually pass error I'm always getting:

[2021-11-05 12:07:01.305178] [0x00007ffff21589c0] [info]

I'm expecting [info] to reflect the severity level I'm passing.

[Edit]

This is the code (Entire code, from .hpp):

#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/trivial.hpp>

enum severity_level { trace, debug, info, warning, error, fatal };
inline boost::log::sources::severity_logger<severity_level> slg;

template <class First> std::string extract_args(First first) {
  if constexpr (std::is_integral_v<First>) {
    return std::to_string(first);
  } else {
    return first;
  }
}

template <class First, class... Args> First extract_args(First first, Args... args) {
  first += extract_args(args...);
  return first;
}

template <class First, class... Args> std::string logging_helper(First msg, Args... args) {
  std::string s_msg = extract_args(msg);

  if constexpr (sizeof...(args)) {
    s_msg += extract_args(args...);
  }

  return s_msg;
}

template <class First, class... Args> inline void log(severity_level level, First msg, Args... args) {
  BOOST_LOG_SEV(slg, level) << logging_helper(msg, args...);
}

If I use as proposed by @Andrey Semashev:

boost::log::trivial::severity_level

I'm getting following error:

cannot convert ‘const boost::log::v2_mt_posix::trivial::severity_level’ to ‘boost::log::v2_mt_posix::sources::aux::severity_level<severity_level>::value_type’ {aka ‘severity_level’}

Solution

  • I suspect, you're using a severity level type different from boost::log::trivial::severity_level while still relying on the default sink. If the default sink can't extract severity level from a log record, it will use boost::log::trivial::severity_level::info as a default.

    You should either use boost::log::trivial::severity_level everywhere, or explicitly configure a sink, with a filter and formatter as necessary. In the latter case you can use your own severity level enum:

    enum severity_level { trace, debug, info, warning, error, fatal };
    
    // Formatting for severity levels
    template< typename Char, typename Traits >
    inline std::basic_ostream< Char, Traits >& operator<<(
        std::basic_ostream< Char, Traits >& strm, severity_level level)
    {
        const char* str;
        switch (level)
        {
        case trace: str = "trace"; break;
        case debug: str = "debug"; break;
        default:
        case info: str = "info"; break;
        case warning: str = "warning"; break;
        case error: str = "error"; break;
        case fatal: str = "fatal"; break;
        }
        strm << str;
        return strm;
    }
    
    inline boost::log::sources::severity_logger<severity_level> slg;
    
    BOOST_LOG_ATTRIBUTE_KEYWORD(a_timestamp, "TimeStamp",
        boost::log::attributes::utc_clock::value_type)
    BOOST_LOG_ATTRIBUTE_KEYWORD(a_thread_id, "ThreadID",
        boost::log::attributes::current_thread_id::value_type)
    BOOST_LOG_ATTRIBUTE_KEYWORD(a_severity, "Severity", severity_level)
    
    // Logging initialization. To be called early in main().
    void init_logging()
    {
        auto core = boost::log::core::get();
    
        // Add commonly used attributes, such as timestamp, thread id, etc.
        core->add_global_attribute("TimeStamp", boost::log::attributes::utc_clock());
        core->add_global_attribute(
            "ThreadID", boost::log::attributes::current_thread_id());
    
        // Construct the sink
        typedef boost::log::sinks::synchronous_sink<
            boost::log::sinks::text_ostream_backend > text_sink;
        boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();
    
        boost::shared_ptr< std::ostream > stream(&std::clog, boost::null_deleter());
        sink->locked_backend()->add_stream(stream);
    
        // Set formatter
        sink->set_formatter(
            boost::log::expressions::stream << "["
                << boost::log::expressions::format_date_time(a_timestamp, "%Y-%M-%d %H:%M:S.%f")
                << "] [" << a_thread_id
                << "] [" << a_severity
                << "] " << boost::log::expressions::smessage);
    
        // Add the sink to core
        core->add_sink(sink);
    }
    
    // ...
    
    template <class First, class... Args> inline void log(severity_level level, First msg, Args... args) {
      BOOST_LOG_SEV(slg, level) << logging_helper(msg, args...);
    }