[log] init_from_settings - problem with applying format and filter

I am trying to use boost::log for tracking application activity. I need message with severity level output to console and more detailed output to file. I have the following code (most of it is copied from boost::log documentation): /* boostLogTest.cpp */ #include <boost/log/sources/severity_logger.hpp> #include <boost/log/sources/record_ostream.hpp> #include <boost/log/utility/init/from_settings.hpp> using namespace boost::log; enum logMessageSeverityLevels { trace = 0 , debug = 1, info = 2, warning = 3, error = 4, fatal = 5 }; #define LOG(x) BOOST_LOG_SEV(logger, x ) typedef boost::log::sources::severity_logger< logMessageSeverityLevels > loggerType; loggerType logger(keywords::severity = error); int main() { boost::log::settings setts; //setts["Core"]["Filter"] = "%Severity% >= 0"; //if set - no output anywhere setts["Core"]["DisableLogging"] = false; setts["Sink:Console"]["Destination"] = "Console"; setts["Sink:Console"]["Filter"] = "%Severity% >= 3"; // no output to console in result setts["Sink:Console"]["Format"] = "[%Severity%] %_%"; setts["Sink:Console"]["AutoFlush"] = true; setts["Sink:File"]["Destination"] = "TextFile"; setts["Sink:File"]["FileName"] = "test_%3N.log"; setts["Sink:File"]["Format"] = "[%TimeStamp%] <%Severity%> %_%"; setts["Sink:File"]["AutoFlush"] = true; boost::log::init_from_settings(setts); LOG(info) << "!!!Hello World!!!"; LOG(warning) << "NO TimeStamp and Severity"; LOG(error) << "NO output if Filter is set "; return 0; } result: no output to console file (test_000.log) is being rewritten on each run: [] ** !!!Hello World!!! [] ** NO date [] ** NO severity [] ** NO output if Filter is set if I add #include <boost/log/trivial.hpp> and replace LOG definition with #define LOG(x) BOOST_LOG_TRIVIAL( x ) I get also no console output but TWO! logs: (boostLogTest.log) 1 [2011-Jul-04 12:14:06.331749] [0x73d190] [info] !!!Hello World!!! 2 [2011-Jul-04 12:14:06.338750] [0x73d190] [warning] NO TimeStamp and Severity 3 [2011-Jul-04 12:14:06.339750] [0x73d190] [error] NO output if Filter is set .... ( test_000.log ) [2011-Jul-04 12:14:06.331749] ** !!!Hello World!!! [2011-Jul-04 12:14:06.338750] ** NO TimeStamp and Severity [2011-Jul-04 12:14:06.339750] ** NO output if Filter is set Built with: g++ -Ipath\to\boost -O0 -g3 -Wall -c -fmessage-length=0 -osrc\boostLogTest.o ..\src\boostLogTest.cpp g++ -Lpath\to\boost\libs -oboostLogTest.exe src\boostLogTest.o -lboost_log-mgw45-mt-d-1_46_1 -lboost_log_setup-mgw45-mt-d-1_46_1 Environment: Windows 7 x64 / MinGW (gcc 4.5) / Eclipse Boost version 1.46.1 Boost log from https://boost-log.svn.sourceforge.net/svnroot/boost-log/trunk/boost-logRevis... 603 Boost built with the same toolset. The questions are: - How to configure severity_logger using init_from_settings() to get the custom severity levels in the log? - Why "Format" variables do not work? (and why %TimeStamp% starts to work if using BOOST_LOG_TRIVIAL for output)? - What should be done to make logger append to log (not overwrite)? - Is it possible to log file and line using format variables (only to file)? I had explored boost::log documentation but had not found answers for these questions. Thank you in advance. Yuriy Petrovskiy

On 07/04/2011 03:47 PM, Petrovskiy Yuriy wrote: [snip]
The questions are: - How to configure severity_logger using init_from_settings() to get the custom severity levels in the log?
You have to register any user-defined attribute value types with the library in order to be able to use it with filter and format parsers. This includes your severity level enum. If your type supports insertion and extraction from stream, you can do it by these two lines: boost::log::register_simple_formatter_factory< logMessageSeverityLevels
("Severity"); boost::log::register_simple_filter_factory< logMessageSeverityLevels ("Severity");
See here for more details: <http://boost-log.sourceforge.net/libs/log/doc/html/log/extension/settings.html#log.extension.settings.adding_support_for_user_defined_types_to_the_formatter_parser>
- Why "Format" variables do not work? (and why %TimeStamp% starts to work if using BOOST_LOG_TRIVIAL for output)?
Because you didn't add the TimeStamp attribute to the core. Your log records don't contain time stamps and thus you don't see them in the output. BOOST_LOG_TRIVIAL implicitly initializes the library in its own way, adding the attribute in the process, that's why it works after using it. However, you should not use this macro if you use other ways of initialization (such as from settings).
- What should be done to make logger append to log (not overwrite)?
You should specify open_mode parameter when creating the text file sink, like this: init_log_to_file( keywords::file_name = "my.log", keywords::open_mode = std::ios::app); You can also pass this option to the backend constructor, if you create it explicitly.
- Is it possible to log file and line using format variables (only to file)?
You mean file and line where a log record is made? You can do this, but only if you add file name and line number as attributes to each record. You can wrap in the logging macros to do this automatically.

2011/7/4 Andrey Semashev <andrey.semashev@gmail.com>
On 07/04/2011 03:47 PM, Petrovskiy Yuriy wrote:
The questions are:
- How to configure severity_logger using init_from_settings() to get the custom severity levels in the log?
You have to register any user-defined attribute value types with the library in order to be able to use it with filter and format parsers. This includes your severity level enum.
If your type supports insertion and extraction from stream, you can do it by these two lines:
boost::log::register_simple_formatter_factory< logMessageSeverityLevels
("Severity"); boost::log::register_simple_filter_factory< logMessageSeverityLevels ("Severity"); ...
Thank you, this worked good.
- Why "Format" variables do not work? (and why %TimeStamp% starts to work
if using BOOST_LOG_TRIVIAL for output)?
Because you didn't add the TimeStamp attribute to the core. Your log records don't contain time stamps and thus you don't see them in the output.
How to add it correctly?
- What should be done to make logger append to log (not overwrite)?
You should specify open_mode parameter when creating the text file sink, like this:
init_log_to_file( keywords::file_name = "my.log", keywords::open_mode = std::ios::app);
You can also pass this option to the backend constructor, if you create it explicitly.
Is it possible to do with init_from_settings? I found no corresponding option in documentation. I think it is important feature to be configured through config file|settings.
- Is it possible to log file and line using format variables (only to
file)?
You mean file and line where a log record is made? You can do this, but only if you add file name and line number as attributes to each record. You can wrap in the logging macros to do this automatically.
Is there any standard solution for this? Thank you for guidance. Yuriy Petrovskiy

On 07/04/2011 07:08 PM, Petrovskiy Yuriy wrote:
Because you didn't add the TimeStamp attribute to the core. Your log records don't contain time stamps and thus you don't see them in the output.
How to add it correctly?
There is an example: <http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/attributes.html#log.detailed.attributes.clock> If you're using Boost.Log from SVN trunk, replace boost::make_shared< attrs::local_clock >() with attrs::local_clock().
You should specify open_mode parameter when creating the text file sink, like this:
init_log_to_file( keywords::file_name = "my.log", keywords::open_mode = std::ios::app);
You can also pass this option to the backend constructor, if you create it explicitly.
Is it possible to do with init_from_settings? I found no corresponding option in documentation. I think it is important feature to be configured through config file|settings.
No, there isn't one. The motivation was that this property is usually programmer-defined, not user-defined, and thus it should not be exposed in the config file. You can, however, achieve this functionality through config file by registering your own sink factory. This factory can create the standard text file sink, only with the required options. There is an example: <http://boost-log.sourceforge.net/libs/log/doc/html/log/extension/settings.html#log.extension.settings.adding_support_for_user_defined_sinks>
You mean file and line where a log record is made? You can do this, but only if you add file name and line number as attributes to each record. You can wrap in the logging macros to do this automatically.
Is there any standard solution for this?
No, not out of the box. You could use constant attribute and scoped attributes to achieve that. <http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/attributes.html#log.detailed.attributes.constant> <http://boost-log.sourceforge.net/libs/log/doc/html/log/detailed/utilities.html#log.detailed.utilities.scoped_attributes>
participants (2)
-
Andrey Semashev
-
Petrovskiy Yuriy