I have been trying to get the Boost Log libraries to work with a config file using the:
boost::log::init_from_stream();
method. I use the:
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
method to register the Severity but this does not seem to do anything. When I run the code, I get the following output:
1.[] A regular message
2.[] A warning severity message
3.[] An error severity message
i.e. the severity is missing. When I add this line of code:
boost::log::register_simple_formatter_factory< severity_level, char >("Severity");
It works as expected, i.e. it logs as above but with the severity level. However, when I then try filter by severity in the config file it doesn't work and nothing is ever written to the file, implying that the filter doesn't know what "Severity" is and therefore no records match this filter.
How do I get Boost Log to work with severities and filtering on severity using the init_from_stream method?
Here is the full source code:(adapted from Andrey Semashev, http://boost-log.sourceforge.net/libs/log/example/doc/tutorial_filtering.cpp)
enum severity_level
{
normal,
notification,
warning,
error,
critical
};
std::ostream& operator<< (std::ostream& strm, severity_level level)
{
static const char* strings[] =
{
"normal",
"notification",
"warning",
"error",
"critical"
};
if (static_cast< std::size_t >(level) < sizeof(strings) / sizeof(*strings))
strm << strings[level];
else
strm << static_cast< int >(level);
return strm;
}
BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int)
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
int main(int, char*[])
{
logging::add_common_attributes();
// boost::log::register_simple_formatter_factory< severity_level, char >("Severity"); // when commented out severities are not shown in the log file
std::ifstream configFile_l("config.ini");
boost::log::init_from_stream(configFile_l);
src::severity_logger< severity_level > lg_l;
BOOST_LOG_SEV(lg_l, normal) << "A regular message";
BOOST_LOG_SEV(lg_l, warning) << "A warning severity message";
BOOST_LOG_SEV(lg_l, error) << "An error severity message";
return 0;
}
The config file looks like this:
[Sinks.Full]
Destination=TextFile
FileName=full.log
Format="%LineID%.[%Severity%] %Message%"
Filter="%Severity% > 3" # have also tried Filter = "%Severity% > info/error etc...
So the answer ultimately came from adding:
boost::log::register_simple_formatter_factory< severity_level, char >("Severity");
as aleksandrm8 suggested.
And then the error:
‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE
was solved by adding the following operator overload:
template< typename CharT, typename TraitsT >
inline std::basic_istream< CharT, TraitsT >& operator>> (
std::basic_istream< CharT, TraitsT >& strm, severity_level& lvl)
{
int n = normal;
strm >> n;
if (n >= normal && n <= critical)
lvl = static_cast< severity_level >(n);
else
lvl = normal;
return strm;
}
Which was found here: http://sourceforge.net/p/boost-log/discussion/710021/thread/2b0325f8. I think that possibly other operator overloads might be needed for other filtering, and info can be found about that here: http://www.boost.org/doc/libs/1_55_0/libs/log/doc/html/log/extension/settings.html#log.extension.settings.adding_support_for_user_defined_types_to_the_filter_parser