AAO DRAMA/DRAMA2 C++ Interface
Public Member Functions | Static Public Member Functions | List of all members
drama::logging::Logger Class Reference

Detailed Description

Implementation of a Class supporting Logging within an AAO DRAMA Task.

An object of this type is created automatically as part of the creation of a DRAMA 2 drama::Task object. User code must invoke the open() method to actually open the log file. That can be done in an action or the main line code. Access the logger using the drama::Task::RefTaskLogger() method.

This class implements the GIT LOG_LEVEL action and routines which allow a DRAMA task to log. It also implements a DITS Logging system (see DitsSetLogSys()) which allows logging of internal DRAMA details.

Note
It is assumed the machine time is set correctly.

The LOG_LEVEL action will be created if needed when the constructor is run (e.g. when the drama::Task object is created). The LOG_LEVEL parameter will be created if it does not exist

The Logger class Open() method examines the LOG_LEVEL parameter and the {system_name}_LOG_LEVEL environment variable to determine the default logging levels. The parameter LOG_LEVEL must have the value NONE for the environment variable value to be used. Open() will then set the LOG_LEVEL parameter to the actual logging level.

If {system_name}_LOG_LEVEL environment variable does not exist, then the DRAMA_LOG_LEVEL environment variable will be used, and if that does not exist then a default level of INST,ERROR,MSG is used.

The log file is then opened. The directory for the log file is specified as the second argument to the open call, but if this is specified as a zero length string, the value of the DRAMA_LOGDIR environment variable is examined. If this is not defined, then the current default directory is chosen.

Within the directory, the name of the log file will be {taskname}-{date}.<ver>.log.[.gz] with the UT date in the format "YYYY-MM-DD". For the first file of the day, <ver> is set to "00". If the file already exists, <ver> is incremented until a name is found where no file yet exists.

On the first message on a UT new day, the log file will be closed and a new log file opened using the new date.

<ver> is the log file version number - this number starts are 00 and increased by 1 each time the log system is re-initialised or if the log file (when uncompressed) exceeds 1/2 a Giga-Byte in size.

If compress mode is enabled, then the log file name has ".gz" appended after ".log"

If compress mode is enabled (See the constructor), the log file is compressed as it is written using "gzip" run under "nice". Normally a very high compression ratio is achieved. Note that running this way results in considerable buffering, as data is buffered by the gzip input and output streams to a very large extent. It is suggested that this mode only be used when the amount of data suggests it is appropriate. When compress mode is enabled, SIGPIPE may be generated by a failure of the logger output commands (e.g. disk full). As a result, Logger will catch that signal and ignore it (A message is output to stderr). If the user application is using SIGPIPE is must set up its handler after calling the logging:Logger constructor (but I don't know how it can tell the difference between the Logger pipe failing or its own pipes failing).

The Logger tells DITS to use this class as its logging system, by calling DitsSetLogSys() - this will result in the logger being shutdown when DitsStop() is invoked or if another logging system is enabled. As a result of this feature.

Much logging is done internally by DRAMA. User code can call DitsLogMsg() or use the Logger::Log() method to log messages from application code which must be independent of the logging system being used.

The following logging levels are supported.

Logger maintains an internal mask of the above levels. It and's this if the level passed to it by the Log() routine and if the result is non-zero the message is logged.

The argument to the LOG_LEVEL action and the contents of the environment variable/LOG_LEVEL parameter on startup should be a comma or space separated list of the above names. If prefixed with NO, the level is truned off, otherwise the level is turned on.

The LOG_LEVEL action without any arguments just returns (using MsgOut) the current values. With or without an argument, the LOG_LEVEL action causes the log file to be flushed to disk.

Note
The log file is compatible with GIT only if the environment variable DRAMA2_LOG_GIT_COMPATIBLE is defined. If not, then an extra column giving the thread ID is written to the log file.
To ensure the DRAMA action context is correct, you should register any thread using DRAMA via the RegisterThread() methods. This is done automatically for drama::thread::TAction threaded action implementations and drama::thread::TUface thread UFACE methods. Only threads created by other means need to worry about registering themselves.
Older DRAMA task using GitLogger will not accept the value DRAMA2 in the DRAMA_LOG_LEVEL environment variable. As a result, we cannot always add DRAMA2 as a level to that environment variable. As a work-around, if this variable contains the value USER4, then DRAMA2 will also be set.

#include "logger.hh"

Public Member Functions

 Logger (Task *dramaTask)
 Construct a drama::logging::Logger object. More...
 
 ~Logger ()
 Destructor. More...
 
LogStream CreateLogStream (unsigned level, const std::string &prefix)
 Create and return a log stream object, which can be used for output a log message using C++ stream functions. More...
 
void Log (unsigned level, bool nofmt, const char *prefix, const char *fmt,...)
 Log a message. More...
 
void Log (const IMP_AbsTime *time, unsigned level, bool nofmt, const char *prefix, const char *fmt,...)
 Log a message with a specified event time. More...
 
void Open (const std::string &system, const std::string &dir="", bool compress=false)
 Open the log file. More...
 
void RegisterThread (const Dits___CurActType &dramaContext, std::thread::id threadId=std::this_thread::get_id())
 Register the DRAMA context of a thread. More...
 
void RegisterThread (std::thread::id threadId=std::this_thread::get_id())
 Register the current DRAMA context against a thread. More...
 
void RegisterThread (std::thread::id sourceThread, std::thread::id newThread)
 Register the DRAMA context of one thread against a new thread. More...
 
void Set (unsigned newLevels)
 Enable new logging levels. More...
 
void Unset (unsigned disableLevels)
 Clear particular logging levels. More...
 

Static Public Member Functions

static void SetTimeOffset (long int t)
 Change the time offset. More...
 

Constructor & Destructor Documentation

drama::logging::Logger::Logger ( Task dramaTask)

Construct a drama::logging::Logger object.

Creates a new logger and inserts drama::logging::Logger as the DRAMA logging system in the current DRAMA tasks. Note that DitsAppInit() must have already been invoked. The constructor should only be called before the DRAMA Main loop is entered (unlike) the older GitLogger). The log file is NOT opened at this point, it can be opened or re-opened with the Open() method.

See the class comments for full details.

Parameters
dramaTaskA pointer to the DRAMA task we are part of.
drama::logging::Logger::~Logger ( )

Destructor.

The constructor of the object registers the object with DRAMA. DRAMA will then call an internal Logger() method when DRAMA shuts down or when the logging system is replaced by another. You should not invoke the destructor until after that is done.

Member Function Documentation

LogStream drama::logging::Logger::CreateLogStream ( unsigned  level,
const std::string &  prefix 
)
inline

Create and return a log stream object, which can be used for output a log message using C++ stream functions.

The log messages are actually written to the file when the created object goes out of scope (i.e. its destructor is run).

Note
You should register any thread using DRAMA via the RegisterThread() methods. This is done automatically for drama::thread::TAction threaded action implementations and drama::thread::TUface thread UFACE methods. Only threads created by other means need to worry about registering themselves.
Parameters
levelThe logging level. One of the D2LOG_ macro values
prefixA prefix to the log message, often indicting the function which makes the call.
void drama::logging::Logger::Log ( unsigned  level,
bool  nofmt,
const char *  prefix,
const char *  fmt,
  ... 
)

Log a message.

Explictly log a message

Parameters
levelThe logging level. One of the D2LOG_ macro values
nofmtIf true, don't format the message, presume it is already formatted (improves efficiency for cases where we know that no formatting is needed.
prefixA prefix to the log message, often indicting the function which makes the call.
fmtC printf style format statement, unless nofmt is true, in which case it is just a string to output.
...If nofmt is false, then the arguments to the format.
void drama::logging::Logger::Log ( const IMP_AbsTime *  time,
unsigned  level,
bool  nofmt,
const char *  prefix,
const char *  fmt,
  ... 
)

Log a message with a specified event time.

Explictly log a message, but use the specified time rather then the current time. This allows a scheme which is buffering log messages to ensure the correct time is assoicated with the message.

You should be warned that this message will likely appear out of order with the normal log messages. You may need to sort your log file on the time fields to account for this. To help in identifing such lines - the colon (:) at the end of the time string is replaced by a plus sign (+).

Parameters
timeThe time to associate with the log message. This is an IMP Time structure. You can use routines like ImpTimeNow() to construct these.
levelThe logging level. One of the D2LOG_ macro values
nofmtIf true, don't format the message, presume it is already formated. (improves efficiency for cases where we know that no formatting is needed.
prefixA prefix to the log message, often indicting the function which makes the call.
fmtC printf style format statement, unless nofmt is true, in which case it is just a string to output.
...If nofmt is false, then the arguments to the format.
void drama::logging::Logger::Open ( const std::string &  system,
const std::string &  dir = "",
bool  compress = false 
)

Open the log file.

If the log file is already open, it is closed and opened again (creating a new version number).

Parameters
systemLogging system name - used to access environment variables
dirDirectory into which to put the log file. If an empty string is supplied, will use the value of the DRAMA_LOGDIR environment variable, and if that has no value, the current default directory.
compressIf set true, then the log file is compressed automatically whilst it is being written. Defaults to false. This mode can be overwritten by setting the GIT_LOGGER_COMPRESS or GIT_LOGGER_NOCOMPRESS environment variables. The compressed file has .gz appended to the filename after .log.
void drama::logging::Logger::RegisterThread ( const Dits___CurActType &  dramaContext,
std::thread::id  threadId = std::this_thread::get_id() 
)

Register the DRAMA context of a thread.

If the specified thread logs a message, the DRAMA context will be set to that specified.

Note
You should register any thread using DRAMA via the RegisterThread() methods. This is done automatically for drama::thread::TAction threaded action implementations and drama::thread::TUface thread UFACE methods. Only threads created by other means need to worry about registering themselves.
Parameters
dramaContextThe DRAMA context for the thread.
threadIdThe ID of the thread
void drama::logging::Logger::RegisterThread ( std::thread::id  threadId = std::this_thread::get_id())

Register the current DRAMA context against a thread.

If the specified thread logs a message, the DRAMA context will be set to that of the current thread.

Note
You should register any thread using DRAMA via the RegisterThread() methods. This is done automatically for drama::thread::TAction threaded action implementations and drama::thread::TUface thread UFACE methods. Only threads created by other means need to worry about registering themselves.
Parameters
threadIdThe ID of the thread
void drama::logging::Logger::RegisterThread ( std::thread::id  sourceThread,
std::thread::id  newThread 
)

Register the DRAMA context of one thread against a new thread.

If the specified newThread logs a message, the DRAMA context will be set to that associated with the source thread, if any.

Note
You should register any thread using DRAMA via the RegisterThread() methods. This is done automatically for drama::thread::TAction threaded action implementations and drama::thread::TUface thread UFACE methods. Only threads created by other means need to worry about registering themselves.
Parameters
sourceThreadThe ID of the thread who's previously registered DRAMA thread is to be use.
newThreadThe ID of the new thread to have the same DRAMA context as sourceThread.
void drama::logging::Logger::Set ( unsigned  newLevels)

Enable new logging levels.

Parameters
newLevelsA mask of levels to enable for logging to the log file.
static void drama::logging::Logger::SetTimeOffset ( long int  t)
inlinestatic

Change the time offset.

This is used in testing only - it allows an offset between the current system time and the time used by GitLogger to be specified, to allow testing of things such as the day change over code.

void drama::logging::Logger::Unset ( unsigned  disableLevels)

Clear particular logging levels.

Parameters
disableLevelsA mask of levels to disable for logging to the log file.

The documentation for this class was generated from the following file:

Click here for the DRAMA home page and here for the AAO home page.

For more information, contact tjf@aao.gov.au 

Generated on Mon Feb 22 2016 15:57:53 for AAO DRAMA/DRAMA2 C++ Interface by doxygen 1.8.10