Classes | Defines
contrib/mul/mbl/mbl_log.h File Reference

Flexible and efficient status and error logging. More...

#include <vcl_fstream.h>
#include <vcl_streambuf.h>
#include <vcl_string.h>
#include <vcl_ostream.h>
#include <vcl_set.h>
#include <vcl_map.h>

Go to the source code of this file.

Classes

class  mbl_log_streambuf
 Allows stream-like syntax on logger. More...
class  mbl_log_null_streambuf
 A null streambuf ignores all input. More...
class  mbl_log_output_base
 Base class for destinations of a logging event. More...
class  mbl_log_output_stream
 Outputs log messages to an existing stream (e.g. vcl_cerr). More...
class  mbl_log_output_file
 Outputs log messages to a named file. More...
class  mbl_logger
 Main user logging class - represents a category. More...
class  mbl_log_categories
 This class handles category lists. More...
struct  mbl_log_categories::cat_spec
class  mbl_logger_root
 Singleton, keeps records of logging state. More...

Defines

#define MBL_LOG(my_level, logger, message)

Detailed Description

Flexible and efficient status and error logging.

Author:
Ian Scott
Date:
16-Jan-2005 Good log statements are left in the code, and switched on or off at runtime. To make this feasible, the decision about whether to send a log message should be as efficient as possible. The runtime cost of a switched off mbl_log statement will be no more than an integer comparison, if you have a decent optimising compiler.

These classes are patterned after the log4j logging library, although without all of the sophistication. (We have not copied any code from log4j (or other logging libraries) - just the ideas.)

To send a message to the log you need to do two things - create a logger object, and send a message to it. By creating a logger, you identify a category of logging events. You should create a separate category for each module of your program. However, creating loggers may not be cheap - so it is best not to do it too often.

 mbl_logger my_log("imorphics.easy_stuff.does_halt");

The easiest way to send a log message looks like:

 MBL_LOG(WARN, my_log, "Infinite loop: Time wasted so far " << time() );

The system will have been setup to assign a log level to a particular category. The log levels are EMERG < ALERT < CRIT < ERR < WARN < NOTICE < INFO < DEBUG. The above log message will be sent if the level for category "imorphics.easy_stuff.does_halt" is set to WARN or higher. You can avoid using macros by calling the logger directly

 my_log.log(mbl_logger::WARN) << "Infinite loop: Time wasted so far " << time() << vcl_endl;

The vcl_endl (or a vcl_flush) is necessary to terminate the log line. The problem with this explicit version is that the stream insertion and call to the time() function take place, even if the logging level is set below WARN. Ideally, we would like unsent log messages to take as little time as possible - so that there is no overhead in leaving the log message in your code. To achieve this we can test the log level first

 if (my_log.level() >= mbl_logger::WARN)
   my_log.log(mbl_logger::WARN) << "Infinite loop: Time wasted so far " << time() << vcl_endl;

Of course, you should just use MBL_LOG which handles this for you. Additionally MBL_LOG sorts out termination of the log message without using vcl_endl, allowing you to send multi-line messages in a single log output.

Definition in file mbl_log.h.


Define Documentation

#define MBL_LOG (   my_level,
  logger,
  message 
)
Value:
do { mbl_logger &rlogger = logger; \
    if (rlogger.level() >= mbl_logger:: my_level) {\
      rlogger.mtstart(mbl_logger:: my_level, __FILE__, __LINE__); \
      rlogger.mtlog() << message << vcl_endl; \
      rlogger.mtstop(); } \
  } while (false)

Definition at line 318 of file mbl_log.h.