![]() |
Development Lifecycle »
Debug Tips »
Trace
Intermediate
License: The Code Project Open License (CPOL)
Advanced Logging for all kind of applicationsBy Alex KucherenkoSimple to use classes for logging and tracing. |
VC6, VC7Win2K, WinXP, MFC, Dev, QA
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

This logging module has seven classes: CLog, CFuncLog,
IStoreLog, CWinLog, CFileLog,
CAutoCritic, CLogSimpleLock.
The main class of the Logging module is the CLog class and in
most cases it must be a singleton in the application. Being a Singleton is not a
requirement for it though.
The Second most useful class is CFuncLog. This class is used
to log functions when entering and leaving. Also this class gives the developer
an easy way to log any data. The Class has overloaded operators <<,
that is why adding something to log is very easy.
Figure 1. UML Design Class Inheritance Diagram
As you saw from Figure 1 the module classes are divided on two parts:
1. Storage classes
2. Logging classes
The declaration of IStoreLog:
////////////////////////////////////////////////////////////////////////// // Abstract class set three default function which must support any child. // Any child must support buffered and non-buffered store class IStoreLog { public: virtual ~IStoreLog( void ){}; // virtual destructor virtual int FlushData() = 0; virtual int WriteString( const std::string &Message ) = 0; virtual int SetBufferLimit( long lSize ) = 0; };
Storage classes have the functionality to buffer with data flushing. By
default the storage class must store the data in its own buffer and only on a FlushData function call
will it flush the buffer data to disk or
elsewhere. As you understand the buffer of storage class in mostly cases
are limited by system resources, that is why when the
buffer reaches it's limit it will flush the data automatically. To set the buffer
limit use the function SetBufferLimit. By default the Storage
class implementation must allocate a buffer and only on a SetBufferLimit
function call will it change its size.
To store string into storage use the function WriteString. The
Storage class must have no formatting and store RAW data as is.
In this section we have two classes: CLog - our main
class and CFuncLog - helper class. Class CLog
declared in clog.h and it implementation is in clog.cpp
file. Class CFuncLog declared in cfuncLog.h,
cfunclog.cpp.
Logger classes have special functions which make logging
easier. While logging you can configure trace output: If you have no
need for time then simply set the flag of CLog class using the function SetLogTime to false and
the time will be not be added to the output. Also you can change the output format
of time by calling SetTimeFormat. By default the class
use Long time format. In the header can be found two defines of most
useful time formats. First is a long default to class format, second
is short one format without millisecond in output.
#define DEF_TIME_LONG_STR "%02u:%02u:%02u ms:%03u" #define DEF_TIME_SHORT_STR "%02u:%02u:%02u"
WARNING: time formatting string must always have 4 or less printf formatting templates, otherwise you will have a stack error.
Also for CLog class can be set such properties as:
Message Output Format -
SetMessageFormat and GetMessageFormat
functions
AutoFlush - SetAutoFlush and GetAutoFlush
functions. true mean flushing of storage buffer after
each trace message. Very useful when application is in alpha testing
and have some GPF's in code. Second mode useful when logging needed
for controlling state of application and it's not very critical by
time - this is top perfomance mode of logging system.
For logging in CLog class there are three functions:
LogRawString - trace
raw string without formatting to storage class.
LogString - trace
message with special level and formatting. There are two functions
with the same name, only difference is a format of output string, in
first case is a std::string on second simple char
*.
LogFormatString - formatting function - wrapper
on printf function.
In many cases developer will need more then three categories of
messages that is why in CLog class is virtual function
LevelText. As input parameter it have number of required
LEVEL. Function will return string with Category Name. By default on
Category name class set limitation on 12 symbols, but this can be
changed by SetMessageFormat function template string.
To use Logging in application include into project such headers:
#include "clog.h" #include "cfunclog.h" #include "cwinlog.h" // include it if you want logging into GUI window #include "cfilelog.h" // include it if you want logging into files ...
CFuncLog class is not required it's only simplify
logging of most used features, like: entering and leaving of
function. Special Formatting and all needed to logging operations are
implemented in CLog file. That is why you can choose:
use it or not.
NOTE: CWinLog class store traced messages in
window and are not multiprocess safe. Otherwise for multiprocess
logging can be used only CFileLog class. By Using
CFileLog all traced messages are store in file. All file
operations are synchronized by OS.
CLog *m_pLog = new CLog( new CFileLog( "c:\\log.log" ), LOG_MAX_LEVEL, true );
First parameter of the CLog constructor must be pointer
of class which support IStoreLog interface. In module
are two implementations of IStoreLog virtual class:
CWinLog and CFileLog.
As you understand CWinLog class create GDI window in
which display traced messages and second log class store logging into
file.
As a output file can be used any OS device or named pipe or
something else, which use syntax of CreateFile API
function.
Second parameter is a upper limit of messages. It must be set to needed upper value limit.
So if you set it to 0 then in log output will be only ERROR messages. If you set it to 1 then in log will be ERROR and WARNING messages... and so on.
Third param said to CLog class instance is it a
parent of IStoreLog class instance or not. By default
this value is true. So CLog Class on
destroy delete instance of IStoreLog class
implementation.
CRepTestApp::CRepTestApp()
{
CFuncLog log( m_pLog, "CRepTestApp::CRepTestApp" );
...
}
Such code will add into log entering and leaving of function code.
Here used feature of automatic variables. On Construct into log added
"enter ..." message and on destroy into log
will be added "leave ..." message. To add
something to log you can type such code:
int something = 100; log << something; ...
such code will add 100 into log output.
WARNING: operator << stores log
values in RAW format.
To add message to log correctly use LogString
function of the CFuncLog class.
If you want to store log into any other place then you must write
implementation of IStoreLog class and use it instance as
a constructor param. CAutoCritic and CLogSimpleLock
classes is a wrappers on Critical Section API of windows. Such
classes are implemented in stand alone file with namespace LOGGER
and can be freely used by other IStoreLog class
implementations.
First logger module was implemented in 2000 and after that was rewritten some times. I found that in many cases the Logger system was a requirement for commercial projects, that is why I spent some time and wrote such an easy to use and extendible logger/trace subsystem.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 23 Feb 2002 Editor: Chris Maunder |
Copyright 2002 by Alex Kucherenko Everything else Copyright © CodeProject, 1999-2009 Web18 | Advertise on the Code Project |