|
Boost : |
From: Caleb Epstein (caleb.epstein_at_[hidden])
Date: 2004-10-25 15:28:54
On Mon, 25 Oct 2004 14:41:31 -0400 (EDT), Rob Stewart <stewart_at_[hidden]> wrote:
> From: "Jeff Garland" <jeff_at_[hidden]>
> > 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_at_[hidden]
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk