Boost logo

Boost :

From: Wyss, Felix (FelixW_at_[hidden])
Date: 2002-04-09 13:44:27


In our tracing library, we use the following approach:

#define TRACE(Topic, Level) \
    if(!ShouldTrace((Topic), (Level))) { } else TraceMessage((Topic), __FILE__, __LINE__).Stream()

This macro is then used as follows:

TRACE(MyTopic, LEVEL_STATUS) << "SessionID=" << SessionID << ", State=" << State << ...;

The Stream() member function returns a reference to a an ostream derived class that buffers the trace message. The content of this buffer (including additional information such as timestamp, filename, line number, thread ID, etc.) is sent to the trace sink(s) in the destructor of TraceMessage.

The "Topic" argument is a handle (opaque pointer) to a structure that contains information about the topic, such as current trace level of the topic, list of sinks etc. The Level argument is a value from 0...100 and thus checks as to whether to trace are very cheap (two indirections, integer comparison, and jump). We never conditionally remove tracing in the release build as the increased code size is far outweighed by the advantage of being able to diagnose systems at customer sites.

Felix

-----Original Message-----
From: Jeff Garland [mailto:jeff_at_[hidden]]
Sent: Tuesday, April 09, 2002 09:28
To: boost_at_[hidden]
Subject: RE: [boost] null ostream (was Logging library)

> 9 Apr 2002 07:32:09 +0400 Jeff Garland wrote:
> >
> >-- a null log stream class that has all empty functions. This can be used

Eugene Karpachov wrote:
> How does "null _log_ stream" differ from just "null stream"? AFAIR we
> already have null stream buffer in boost, hence we have null stream.

The problem is that the null stream buffer still has the overhead of the ostream class calling into
the stream buffer to do nothing. That is, the logging will still have some performance impact on
production code. My goal was to have zero impact.

A traditional solution to what I was after would be to use the ugly macros throughout the code:

void f() {

   //some code
   #ifdef DEBUG
     logger << "log data" << endl;
   #endif
}

In a large program you could wind up with thousands of these macros polluting the code. So with
null stream you have one #ifdef to set the stream to either an ostream or null stream. The rest of
the code is written without conditional logic:

void f() {
  //some code
  logger << "log data" << endl; // optimized out by the compiler in release builds
}

So null ostream and null stream buffer serve different purposes. null stream buffer can be switched
at runtime while null ostream is switched at compile time.

Jeff

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk