Click here to Skip to main content
15,886,074 members
Articles / Programming Languages / C++

Thread-safe Logger with Automatic Removing Log Messages from Release Version

Rate me:
Please Sign up or sign in to vote.
5.00/5 (6 votes)
13 Sep 2000 104.2K   1.4K   31   12
A log file class for multi-threaded applications

Introduction

This class makes it possible to use log file in multi-threaded applications and has several useful features widely used in my multi-threaded, time sensitive projects where Visual C++ integrated debugger has very limited usage.

CDebugPrintf class provides some useful features:

  1. Thread-safe logging in multi-threaded applications.
  2. Automatic removing log messages from release version of your application.
    You don't need anymore to remove or comment log messages in release version. Release version will not have any overhead or unused information in executable file.
  3. You can write log messages at the same time to same file from different applications.
    It is useful when it is necessary to explore interaction and timing issues between two or more applications.
  4. Using printfs style for format text: %s, %d, %4.1d, etc.
    Sorry, but there is no floating point support.
  5. Data and time stamps for each message in log file.
    Also, this class provides time difference stamp from application start.
  6. Console output and easy logging for error codes returned by GetLastError function.
  7. Saving old log files.
  8. Uses only Windows API functions. So it can be used even in non-MFC applications.

The class is easy to use.

  1. Include files dbg.h and dbg.cpp to your project.
  2. At any time you want to write something to the log file, use the PRINTF macro.

Example of Log File Output

0.000 08/25/2000 15:04:48  User name = KVA
0.015 08/25/2000 15:04:48  ISAPI = "TraxDataMgr.dll"
0.015 08/25/2000 15:04:48  CActionHandler constructor
0.015 08/25/2000 15:04:48  CDataMgrActionHandler constructor
5.123 08/25/2000 15:04:53  0   HttpExtensionProc: started
5.123 08/25/2000 15:04:53  Execute request 1 started.   
5.672 08/25/2000 15:04:53  CIndexer constructor: done
5.693 08/25/2000 15:04:53  Open:  D:\Data\Docs\customer
5.693 08/25/2000 15:04:53  Loading index table from 'D:\Data\Docs\customer.idx'
5.693 08/25/2000 15:04:53  Count: 93560
6.132 08/25/2000 15:04:54  Index loading finished ... OK
6.375 08/25/2000 15:04:54  Execute request 1 finished.   
6.375 08/25/2000 15:04:54  0   HttpExtensionProc: finished

Class Usage

C++
void SomeFunction( char* arg1, int arg2, string& arg3 )
{
    // doing something
    ...
    PRINTF("Something happened by using %s and %d arguments", arg1, arg2);
    ...
    // doing something
    ...
    PRINTF(arg3);
    ...
    SHOW_CONSOLE();
    PRINTF("This message is visible on console and in log-file.");
}

Remarks

All log messages must fit into one line of source code because of problem with transparent removing log messages from release version.

C++
PRINTF("One line messages are supported.");
C++
PRINTF("Multi-line messages %s %s",
           "are not",
           "supported.");

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questioncan this be used in Linux Project Pin
pkuwgg8-Sep-08 16:25
pkuwgg8-Sep-08 16:25 
GeneralWorks great! Pin
Luckymmkay31-Aug-07 4:39
Luckymmkay31-Aug-07 4:39 
GeneralPossible memory corruption Pin
Tnarol6-Jul-06 2:17
Tnarol6-Jul-06 2:17 
GeneralAn enhancement to class Pin
Wes Jones13-Jun-01 9:31
Wes Jones13-Jun-01 9:31 
GeneralProblems w/ Console window Pin
Wes Jones24-May-01 15:25
Wes Jones24-May-01 15:25 
GeneralRe: Problems w/ Console window - half way fixed! Pin
Wes Jones25-May-01 13:33
Wes Jones25-May-01 13:33 
I still don't know why my app sometimes hangs until I press Ctrl+C.
I did the find the way to prevent a windows application that is using a console window for std output (such as with the code from this article) from exitting when Ctrl+C is pressed.

The code to prevent Ctrl+C(on your console window) from killing your app looks like this:

BOOL WINAPI ConsoleCtrlEvent_Handler(DWORD dwCtrlEvent)
/////////////////////////////////////////////////////
// See documentation for SetConsoleCtrlHandler()
//
//	
// This function handles console window events such as
// Ctrl+C -- which by default will call ExitProcess() (and your app will exit)
//
// This function ignores the Ctrl+C event so that your program isn't closed.
{
	switch(dwCtrlEvent)
	{
	case CTRL_C_EVENT:  //The console window had the reveived the Ctrl+C event
                            //I don't want this to kill my app
			    //so I just return TRUE so that windows will consider
			    //this event handled.

		return TRUE;//<-- this console event has been handled

	case CTRL_BREAK_EVENT:	//let the default handlers get called 
	case CTRL_CLOSE_EVENT:	//for these console events
	case CTRL_LOGOFF_EVENT:
	case CTRL_SHUTDOWN_EVENT:
	default:
		return FALSE;//<-- call the next console event handler

	}
}

Note that the CTRL_CLOSE_EVENT will cause the system to display the 'End Program' dialog box. The best way to help prevent this is to disable the close button on the console window.

Here is code I found to remove the close button from the console window:
HWND GetConsoleHwnd()
{    
	#define MY_BUFSIZE 1024 // buffer size for console window titles    
	 HWND hwndFound;         // this is what is returned to the caller    

	TCHAR pszNewWindowTitle[MY_BUFSIZE]; // contains fabricated WindowTitle    
	TCHAR pszOldWindowTitle[MY_BUFSIZE]; // contains original WindowTitle    
	// fetch current window title    
	GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);    
	// format a "unique" NewWindowTitle    
	_stprintf(pszNewWindowTitle,_T("%d/%d"), GetTickCount(), GetCurrentProcessId());    
	// change current window title    
	SetConsoleTitle(pszNewWindowTitle);    
	// ensure window title has been updated    
	Sleep(40);    
	// look for NewWindowTitle    
	hwndFound = FindWindow(NULL, pszNewWindowTitle);    
	// restore original window title    
	SetConsoleTitle(pszOldWindowTitle);    
	return(hwndFound);
}

BOOL DisableConsoleClose()
{   
    return RemoveMenu(GetSystemMenu(GetConsoleHwnd(), FALSE),
		    SC_CLOSE, MF_BYCOMMAND);
}

then where you call AllocConsole():
if( AllocConsole() )
{
       DisableConsoleClose();
       SetConsoleCtrlHandler( ConsoleCtrlEvent_Handler, TRUE)//install the handler
}

and where you call FreeConsole():
SetConsoleCtrlHandler(ConsoleCtrlEvent_Handler, FALSE);//un-install the handler
FreeConsole();

GeneralShouldn't CDebugPrintf::HideConsole() be... Pin
8-Feb-01 11:48
suss8-Feb-01 11:48 
GeneralFix for Multi-Line comment Pin
Brad Bruce14-Sep-00 12:10
Brad Bruce14-Sep-00 12:10 
GeneralAdd ThreadID Pin
Mark Findlay14-Sep-00 9:59
Mark Findlay14-Sep-00 9:59 
GeneralRe: Add ThreadID Pin
James Spibey21-Dec-00 22:25
James Spibey21-Dec-00 22:25 
GeneralRe: Add ThreadID Pin
17-Apr-01 3:43
suss17-Apr-01 3:43 
GeneralRe: Add ThreadID Pin
25-Nov-01 0:21
suss25-Nov-01 0:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.