Re: [boost] [Review] Boost.Logging: formal review

----Original Message---- From: Richard Glanmark [mailto:Richard.Glanmark@neonet.biz] Sent: 15 December 2005 08:33 To: boost@lists.boost.org Subject: Re: [boost] [Review] Boost.Logging: formal review
Some thoughts and ideas about some of the topics that has been discussed regarding the proposed Boost.Logging library.
1. Enabled/disabled logger, logging macros and efficiency
The logging macro BOOST_LOG should accept two arguments instead of one. The logger and the log message. The syntax
(1) BOOST_LOG(some_log) << "my message " << foo() << bar();
should be replaced with
(2) BOOST_LOG(some_log, "my message " << foo() << bar());
and the macro being defined something like this
(3) #define BOOST_LOG(logger, msg) \ if(logger.isEnabled()) { /* code that logs msg */ ... }
The current definition is (I believe) #define BOOST_LOG(logger) \ if(!logger.isEnabled()) {} else logger Which achieves the same ends. In particular, foo() is not called unless logging occurs. -- Martin Bonner Martin.Bonner@Pitechnology.com Pi Technology, Milton Hall, Ely Road, Milton, Cambridge, CB4 6WZ, ENGLAND Tel: +44 (0)1223 441434

On 12/15/05, Martin Bonner <martin.bonner@pitechnology.com> wrote:
----Original Message---- From: Richard Glanmark [mailto:Richard.Glanmark@neonet.biz] Sent: 15 December 2005 08:33 To: boost@lists.boost.org Subject: Re: [boost] [Review] Boost.Logging: formal review
Some thoughts and ideas about some of the topics that has been discussed regarding the proposed Boost.Logging library.
1. Enabled/disabled logger, logging macros and efficiency
The logging macro BOOST_LOG should accept two arguments instead of one. The logger and the log message. The syntax
(1) BOOST_LOG(some_log) << "my message " << foo() << bar();
should be replaced with
(2) BOOST_LOG(some_log, "my message " << foo() << bar());
and the macro being defined something like this
(3) #define BOOST_LOG(logger, msg) \ if(logger.isEnabled()) { /* code that logs msg */ ... }
The current definition is (I believe)
#define BOOST_LOG(logger) \ if(!logger.isEnabled()) {} else logger
Which achieves the same ends. In particular, foo() is not called unless logging occurs.
But there is some additional overhead with the implementation in the proposed (and withdrawn) Logging library. The conditional actually creates a temporary object (enabled_logger) that contains a pointer to a heap-allocated stringstream (in the case of the log being enabled). This stream then used as the target for the << operations. When the temporary goes out of scope (e.g. at the end of the logging statement) the stringstream contents are flushed to the actual log object. This temporary object is created even in the case of the log being disabled, though the << formatting is never invoked and there is no heap allocation of a stringstream. I for one agree with Richard that any macro interface to logging should work by surrounding the entire invocation in parens, not just the log object. It would remove the need for the enabled_logger class and the additional heap allocation of the stream. -- Caleb Epstein caleb dot epstein at gmail dot com

The current definition is (I believe)
#define BOOST_LOG(logger) \ if(!logger.isEnabled()) {} else logger
Which achieves the same ends. In particular, foo() is not called unless logging occurs.
But there is some additional overhead with the implementation in the proposed (and withdrawn) Logging library. The conditional actually creates a temporary object (enabled_logger) that contains a pointer to a heap-allocated stringstream (in the case of the log being enabled)
This is implementation detail of submitted library (mistake IMO) and should not affect overall preferance on interface. It is possible to implement filtering part efficiently without need for extra memory allocation and unnecessary work In my production projects in performance critical application I also use one global variable that guard all DEBUG trace statements. Gennadiy

I for one agree with Richard that any macro interface to logging should work by surrounding the entire invocation in parens, not just the log object. It would remove the need for the enabled_logger class and the additional heap allocation of the stream.
Yes, you're right. If I can't eliminate the creation of the stream, I'll prefer that. But as Gennady said, I will make it possible for you to create your own macros -- I'll just provide the means ;) Best, John -- John Torjo, Contributing editor, C/C++ Users Journal -- "Win32 GUI Generics" -- generics & GUI do mix, after all -- http://www.torjo.com/win32gui/surfaces.html - Sky's the limit! -- http://www.torjo.com/cb/ - Click, Build, Run!
participants (4)
-
Caleb Epstein
-
Gennadiy Rozental
-
John Torjo
-
Martin Bonner