I'm using Boost-Log 2.0, which has some differences from version 1, and I have a hard time outputting the "Severity" attribute.
I'm using the "Boost.Format-style" formatters
"%TimeStamp% [%Uptime%] (%LineID%) <%Severity%>: %Message%"
TimeStamp
, LineID
, and Message
are common_attributes
. Uptime
is an attribute I added using attrs::timer()
. I thought that Severity
was automatically added when using severity_logger
, but apparently it isn't and that's my problem. I get empty severities, eg:
2013-Apr-06 19:21:52.408974 [00:00:00.001337] (3) <>: A warning severity message
Notice the empty <>
. I've tried to add severity using register_simple_formatter_factory
but then I get the compiler error :
error: no matching function for call to ‘register_simple_formatter_factory(const char [9])’
and I don't get why.
Here's my code :
#include <iostream>
#include <boost/log/common.hpp>
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/formatter_parser.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/severity_feature.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/attributes.hpp>
using namespace std;
namespace logging = boost::log;
namespace expr = boost::log::expressions;
namespace attrs = boost::log::attributes;
namespace src = boost::log::sources;
namespace keywords = boost::log::keywords;
enum severity_level
{
DEBUG,
INFO,
WARNING,
ERROR,
CRITICAL
};
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, src::severity_logger_mt< severity_level> )
// The formatting logic for the severity level
template< typename CharT, typename TraitsT >
inline std::basic_ostream< CharT, TraitsT >& operator<< (
std::basic_ostream< CharT, TraitsT >& strm, severity_level lvl)
{
static const char* const str[] =
{
"DEBUG",
"INFO",
"WARNING",
"ERROR",
"CRITICAL"
};
if (static_cast< std::size_t >(lvl) < (sizeof(str) / sizeof(*str)))
strm << str[lvl];
else
strm << static_cast< int >(lvl);
return strm;
}
void init() {
// logging::register_simple_formatter_factory< severity_level >("Severity");
logging::add_file_log(
keywords::file_name = "blop.log",
keywords::auto_flush = true,
keywords::open_mode = (std::ios::out | std::ios::app),
keywords::format = "%TimeStamp% [%Uptime%] (%LineID%) <%Severity%>: %Message%"
);
logging::add_common_attributes();
logging::core::get()->add_global_attribute("Uptime", attrs::timer());
}
int main(int argc, const char *argv[]) {
init();
src::severity_logger_mt< severity_level > lg = my_logger::get();
BOOST_LOG_SEV(lg, DEBUG) << "A debug severity message";
BOOST_LOG_SEV(lg, INFO) << "An informational severity message";
BOOST_LOG_SEV(lg, WARNING) << "A warning severity message";
BOOST_LOG_SEV(lg, ERROR) << "An error severity message";
BOOST_LOG_SEV(lg, CRITICAL) << "A critical severity message";
return 0;
}
Notice the commented-out line :
// logging::register_simple_formatter_factory< severity_level >("Severity");
which produces the mentioned error.
I compile it with:
g++ main.cpp -Wall -DBOOST_ALL_DYN_LINK -lboost_system -lboost_log_setup -lboost_log -lboost_filesystem -lboost_date_time -lboost_thread -o main
Here's the prototype of
register_simple_formatter_factory
function template:That means you forgot
typename CharT
, so, here's the correct one:Or some other character types, like
wchar_t
.The reason could be that you shouldn't write data to std::ostream. boost.log uses boost.log.formatting_ostream to output logs, not std::ostream. please see the this code extracted from page http://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/log/detailed/expressions.html
You can make your own backend and call set_formatter on it. Here's my code showing how to do it plus a few additions like the log file cleanup and auto flush:
also you can set the logging level as:
note: This code is from my own repository. dreamdridge is the product name, hence the namespaces.
Correcting the call to register the formatter (i.e.
operator<<
) as pointed out by the answers from W. Merrt and Matt Yang is all you need to make your current code compile and run correctly.However, in order to make full use of Boost Log's filtering capabilities you also need to define
operator>>
for your custom severity levels and then register that method with the filter factory.Ran into the same problem (blank %Severity% in the log file AND the same compiler error when trying to add the register function). I found that the call to register_simple_formatter_factory should be: