
On Mon, 25 Oct 2004 14:41:31 -0400 (EDT), Rob Stewart <stewart@sig.com> wrote:
From: "Jeff Garland" <jeff@crystalclearsoftware.com>
On Fri, 22 Oct 2004 17:16:14 -0400 (EDT), Rob Stewart wrote
There are also plenty of times in which you want logging available in release builds but you want minimal overhead when it is disabled. A macro helps there, too, by moving the evaluation of the argument list into the body of a conditional statement.
Well, personally, I'd really like to try and go macro-less on the logging approach. I don't like macros because:
1) The logging code will be in the release build anyway (for all industrial apps I've seen this is the case).
Some logging is debug only and really shouldn't be in the release build. If the mechanism makes the overhead nothing more than a Boolean test, without side effect argument evaluation, etc., you could leave it in. Even then, each of those conditionals might trigger a bad guess by early stages of a process pipeline, so it might have deleterious effects on performance.
I find great utility in being able to leave debug-type logging statements in production code and enable them as-needed when the situation arises (e.g. through sending an extrnal signal or command to a process). This dictates that the "is_enabled" check be very inexpensive, and that when it fails the log message should not even be formatted.
2) Macro systems tend to be fragile -- pass it bad type (eg:string instead of char*) and it might crash your app. In this day and age the compiler should detect these errors...
If the macro does very little, such as produce a conditional followed by one line of code, there's not much room for this problem. It is also easy to see the definition of such a macro to understand how it works.
This is how the code John submitted works. A logging call looks like: BOOST_LOG (log_name) << the << things << to << output; not (as I've more commonly seen, and even done myself): LOG (log_name, the << stuff << to << output); or even (note multiple parens): ACE_LOG ((LM_INFO, "Some %glyph string", args ...)) I think John's approach is minimally intrusive and the usage of iostreams makes it pretty much impossible to mess anything up. I'm sure he can come up with a way that it can be used without macro as well (e.g. perhaps a boost::log method). As it stands now, it can be done but you'd be stuck with lines like: *(boost::log::log_id<log_stream_logid_type>::unique_id().m_stream) << some_message; Which is a lot harder to type than BOOST_LOG(log_stream) :-) I am not a fan of macros, and avoid them where possible, but I think they are the least painful solution to a problem like this one. -- Caleb Epstein caleb.epstein@gmail.com