TRACER -- Reusable Class to Make Traces to Log File and External Trace Window
Posted
by Rajeev Sadasivan
on December 6th, 2002
Environment: Windows 2000 SP2, VC6 SP3
- MFC is NOT needed.
- File logging and Trace to Window (OR BOTH) are possible. Set it by using the TRACE_INIT macro.
- Trace Window per process OR one within a machine is possible. Set it by using the TRACE_INIT macro.
- Maximum trace file size is controlled. Set it with TRACE_INIT. Just give 1, 2, 3...10 for size in MB.
- Trace Macros can be used just like ostream << outputs.
- TRACER_STREAM("My test value is" << value1 << "String = " << String)
- For printf like trace, use TRACER.Print("Value = %d, Value %s", value1, valueString)
- To easily distinguish between lines, use Progress, error, exception, message markers in Print() statement. Refer to TraceMaker.h for these markers.
- To log function entry and exit, use TRACE_FUNCTION_IN(). It will automatically add "Leaving from Function xyz in the trace window&file".
- Include TraceMaker.cpp and TraceMaker.H in the project and start using it. First, set the trace file name (if file logging is needed), maximum log file size, trace mode (window, file, or both), trace window mode using TRACE_INIT() macro.
- A precompiled header is not necessary. If needed, uncomment #include "stdafx.h" in the TraceMaker.cpp file.
- Enable/Disable trace by defining TRACER_ENABLED.
To see the working, left/right mouse click OR double-click it. Trace will be added to the window and file. Also, watch CTraceAppApp::InitInstance() to see the usage of the tracer macros/functions. See sample source code below.
BOOL CTraceAppApp::InitInstance()
{
TRACE_INIT( _T("C:\\_MyTraceLog.txt"),
2 /* MB */,
FILE_AND_WINDOW /* Log file & window is needed */,
true /* One WIndow Per Process */);
TRACE_FUNCTION_IN(_T("CTraceAppApp::InitInstance()"));
int nValue = 45678;
float fValue = 2398.1039f;
char cFirst = 'R';
char *String1 = "Tracer Test-1";
TRACER_STREAM("1. TRACER_STREAM; These are my values "
<< nValue << fValue << cFirst << String1 << "\r\n");
TRACER.Print(_T("2. TRACER.Print; These are my values %d, %f,
%c, %s"),
nValue, fValue, cFirst, String1);
TRACER.Print(TRACER_OPE_PROGRESS, _T("Application Init
in progress"));
// Standard initialization
AfxEnableControlContainer();
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a
// shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC
// statically
#endif
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something
// appropriate, such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(); // Load standard INI file options
// (including MRU)
// Register the application's document templates. Document
// templates serve as the connection between documents, frame
// windows, and views.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CTraceAppDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CTraceAppView));
AddDocTemplate(pDocTemplate);
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and
// update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
void CTraceAppView::OnLButtonDown(UINT nFlags, CPoint point)
{
// To log entry and exit of the function.
TRACE_FUNCTION_IN(_T("CTraceAppView::OnLButtonDown()"));
// Logging using << operator.
TRACER_STREAM(" L button clicked " << point.x << point.y
<<"\r\n");
// Trace marker can also be printed. Using first parameter.
// Format is same as printf.
TRACER.Print(TRACER_OPE_ERROR, _T("Error Here"));
CView::OnLButtonDown(nFlags, point);
}
void CTraceAppView::OnRButtonDblClk(UINT nFlags, CPoint point)
{
// To log entry and exit of the function.
TRACE_FUNCTION_IN(_T("CTraceAppView::OnRButtonDblClk()"));
// Simple printf like logging.
TRACER.Print(_T("Right button double clicked at point %d, %d"),
point.x, point.y);
CView::OnRButtonDblClk(nFlags, point);
}
void CTraceAppView::OnRButtonDown(UINT nFlags, CPoint point)
{
TRACE_FUNCTION_IN(_T("CTraceAppView::OnRButtonDown()"));
// Using Exception marker; No newline is added at END;
// So write "\r\n".
TRACER_STREAM(" Right button clicked at" << point.x << point.y
<< "\r\n");
try
{
int nDrawIncrment = m_nMaxSize / (prevPoint.y - point.y) ;
}
catch(...)
{
// Using Exception marker; Newline is added at END.
TRACER.Print(TRACER_OPE_EXCEPTION, _T("OnRButtonDown -
division by ZERO"));
}
CView::OnRButtonDown(nFlags, point);
}
void CTraceAppView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
TRACE_FUNCTION_IN(_T("CTraceAppView::OnLButtonDblClk()"));
// Without any markers. Newline is added at END.
TRACER.Print(_T("Left button double clicked at %d, %d"),
point.x, point.y);
// Using error trace marker.
if (point.x > m_nMaxSize)
TRACER.Print(TRACER_OPE_ERROR, _T("Invalid point"));
CView::OnLButtonDblClk(nFlags, point);
}

Comments
Small bug and solution
Posted by Legacy on 10/02/2003 12:00amOriginally posted by: DAKOT
ReplyMemory leak and solution...
Posted by Legacy on 08/29/2003 12:00amOriginally posted by: Baptiste Pierard
Reply
Generalized one that everybody will make use of
Posted by Legacy on 12/08/2002 12:00amOriginally posted by: R.Sundararaman
Good work.
ReplyYou can generalize the tracer window instead of creating your own window by having a member m_hwnd. But in that case,
the result window should be writable( editable ).
Fine work once again.
Thankx
Stay on top / Autoscroll
Posted by Legacy on 12/08/2002 12:00amOriginally posted by: Michal Mecinski
Good work and very useful.
I would make two small changes:
- make the output window stay on top of other windows
- scroll the output down after you add new lines
This would make tracing a bit easier.
Thank you.
ReplyAdd OutputDebugString
Posted by Legacy on 12/06/2002 12:00amOriginally posted by: Enda Mannion
Reply