|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionThe problem when debugging a multi-tier system (with perhaps multiple languages) is that traces are placed in different log files, in different formats, and in different locations on the network. What is TraceTool
TraceTool Overview
How it WorksTraces are sent to the viewer using Except for the C++ Framework, traces are buffered in a message list and sent by another thread. Before StartingThe first thing to do before testing the client code is to run the viewer once, for self-registration. Put the viewer in the right place (in program files\TraceTool, for example) and run it. The viewer will add this icon on the tray bar: It's not a COM server that registers interfaces and some rights, but writes the path to itself into the registry so that clients can launch it if necessary. Right click on this icon to show the following menu:
Click the "Show" item to display the viewer. You can also double click the icon on the tray bar. Using the CodeThe Framework is composed of three master classes:
See the Sending traces is very easy; just use one of the three TraceNode.Send MethodEach trace is composed of two columns. The second column is optional. The following C# code shows different examples: using TraceTool ;
...
TTrace.Error.Send ("Hello world") ;
TTrace.Warning.Send ("Hello" , "world") ;
TraceNode Hello = TTrace.Debug.Send("Hello") ; // keep node reference
Hello.Send ("world") ; // use node to send sub trace
// or in one line :
TTrace.Debug.Send ("Hello").Send ("world") ;
It produces the following output:
Delphi sample: uses TraceTool,
...
TTrace.Warning.Send('hello' , 'world') ;
Java sample: import TraceTool.* ;
...
TTrace.Warning().Send("hello" , "world") ;
C++ sample: #include "tracetool.h"
...
TTrace::Debug()->Send ("Hello");
ActiveX sample (JScript): var TTrace = new ActiveXObject("TraceToolCom.XTrace");
...
TTrace.Debug.Send("hello from jScript") ;
Tree indentation can also be done using the TTrace.Debug.Indent ("Begin of procedure") ;
TTrace.Debug.Send ("inside procedure" ) ;
TTrace.Debug.Send ("Do some work" ) ;
TTrace.Debug.UnIndent ("end of procedure") ;
Multiple Window TabYou can send traces in a separate window tab: WinTrace myWinTrace ;
myWinTrace = new WinTrace ("MyWINID", "My trace window");
myWinTrace.Debug.Send ("Hello",
"Can be used to store exceptions, for examples");
You can access the main The Each window can automatically save traces in an XML file at real time. To set the file name, you can use the
Multiple Column TracesThe original Framework allows you to send two columns of information (including thread name, icon, and date). It's now possible to send as many columns as you want, but with a small restriction: multi-column is not supported in the main trace window, since many applications (and in different languages) cannot share the main window in "classic" mode and in "multi-column" mode. You must then create a window trace and set the column titles (with just a few lines). In that mode, of course, you lose the automatic thread name and date. You must send them yourself if you need to. Sending many columns of text is performed with the same API as for simple trace. Just add a tabulation ("\t" or char 9) between the different columns. Here is a C# example: WinTrace MultiColTrace ;
public void initTrace()
{
// create the window
MultiColTrace = new WinTrace ("MCOL",
"MultiCol trace window") ;
// set the window to multi column mode.
// That automatically remove all columns
MultiColTrace.SetMultiColumn () ;
// must be called before calling setColumnsTitle
// add columns title
MultiColTrace.SetColumnsTitle("col1 \t col2 \t col3");
// columns titles must separated by tabulations
// change the active window (optional)
MultiColTrace.DisplayWin() ;
}
Once initialized, use this new // columns data must be separated by tabulations
MultiColTrace.Debug.send("1 \t 2 \t 3") ;
Info PaneThe info panel displays additional information for a specific trace. When available, a small blue circle is visible on the gutter. This can be the object view, dump, stack, or any data that can be displayed in a maximum of three columns. The "Info" button on the toolbar shows or hides this panel. SendObject and SendType Methods
TTrace.Debug.SendType ("this type", this.GetType() );
TTrace.Debug.SendObject ("this object", this );
SendValueIf object obj;
obj = null;
TTrace.Debug.SendValue ("null Object", obj);
obj = new Object();
TTrace.Debug.SendValue ("Object instance", obj);
obj = 123;
TTrace.Debug.SendValue ("integer Object", obj);
obj = "str";
TTrace.Debug.SendValue ("string", obj);
// simple array of Integer
int[] VtArr = new int[10]{7,1,5,2,0,3,4,8,6,9};
TTrace.Debug.SendValue ("simple array", VtArr);
Here is another screenshot for a complex multidimensional array with user defined bounds and types:
As you can see in the previous example, SendDump
TTrace.Debug.SendDump ("Dump test", "Unicode",
System.Text.Encoding.Unicode.GetBytes(str) ,50) ;
SendBitmapTTrace.Debug.SendBitmap("Bitmap", pictureBox1.Image);
XMLnodeEx.AddXML("<data> Hello XML </data>");
Table
// create the table
TraceTable table = new TraceTable();
// add titles. Individual or multiple columns titles
// can be added, separated by tabs
table.AddColumnTitle("colA"); // first column title
table.AddColumnTitle("colB"); // second column title
table.AddColumnTitle("title column C\tcolD"); // other columns title
// add first line. Individual or multiple columns data
// can be added columns, separated by tabs
table.AddRow();
// add first col
table.AddRowData("a");
// then add other columns (tab separated)
table.AddRowData("b" + "\t" + "c" + "\t" + "d" + "\t" + "e");
// add second line
table.AddRow();
// add all columns data in a single step (tab separated)
table.AddRowData("aa" + "\t" + "data second column" +
"\t" + "cc" + "\t" + "dd" + "\t" + "ee");
// finally send the table
TTrace.Debug.SendTable("Mytable", table);
SendStack and SendCaller Functions
TTrace.Debug.SendStack ("Stack test" , 0) ;
TTrace.Debug.SendCaller ("Caller test" , 0) ;
Resendxxx and Appendxxx FunctionsOnce a node is sent, you have the possibility to change the text. For example, send the "Start.." text, and when an operation is completed, append the "Done" text, or replace one of the two columns with a new text: TraceNode start1 = TTrace.Debug.Send ("Start 1 ..") ;
start1.ResendRight ("Done") ;
TraceNode start2 = TTrace.Debug.Send ("Start 2 ..") ;
start2.AppendLeft ("Done") ;
Note that the time is not changed. WatchesIf you want to follow the values of a variable, you can send it using the classic
TraceNodeEx: A More Easier Way to Create Complex TracesIn place of overloading the You must specify the parent node trace in the constructor parameter. The parent You can specify the text of the columns separately, specify the icon to use, add object and type, or add Dump to the associated 'Detail' tree. When the node is completed, just call its // Create an unicode string with special
// char in front and at the end.
string str = '\u2250' + "azertyuiop qsdfghjklm" + '\u9999' ;
// Create a trace node with the same icon and
// Enabled properties as TTrace.Debug
TraceNodeEx node = new TraceNodeEx (TTrace.Debug) ;
// Fill it
node.LeftMsg = "hello" ;
node.RightMsg = "world" ;
node.IconIndex = 8 ;
node.AddDump (
System.Text.Encoding.Unicode.GetBytes(str) ,50) ;
node.AddDump (
System.Text.Encoding.ASCII.GetBytes(str) ,50) ;
node.AddObject (str) ;
// and finally send it
node.Send () ;
The Log FileThe viewer can append traces into an XML file (single filename or daily filename). Since the version 10.1, it's now possible to append to this kind of file without having the viewer running, using the client API. The same JavaScript TracingThe The best way to load the library is ask the viewer to send the script. Add this line on the body tag : <script type="text/javascript"
src="http://localHost:81/tracetool.js?Compressed=true" no-cache></script>
Note that by default the HTTP port is disabled on the viewer to not interfere with the existing Web server. You must change the HTTP port (81 for example) on the Option menu. See the documentation (Word) for configuration. The API is given with complete documentation in HTML using Google jsdoc-toolkit 2 (created from the JavaScript To allow sending traces to another server as the original page (Cross domain communication), the API does not use Ajax (Single domain) but dynamic script creation. Traces are encoded and passed in parameter to the viewer. Large trace messages are split into multiple scripts. Pocket PC DevelopmentThe Other Trace Framework SupportThe
A bridge is provided for all these famous Frameworks. See the System.Trace (.NET) SupportThe classic Microsoft Trace.Listeners.Clear() ;
Trace.Listeners.Add (new TTraceListener ()) ;
int[] myArray = new int[3] { 3, 5 , 5};
Trace.WriteLine ("TraceListener demo") ;
Trace.Write ("myArray : ") ;
Trace.WriteLine (myArray) ;
That works fine, of course, but you lose abilities to display object information, array values, dumps, stack, ... Microsoft Enterprise Framework (.NET) SupportMicrosoft Enterprise Framework (EIF) traces can be redirected to the viewer using the Sample EIF demo: private static EventSource myEventSource =
new EventSource("EIFDemo");
[STAThread]
static void Main(string[] args) {
// sample 1 : use static ErrorMessageEvent
// msg, severity, error code
ErrorMessageEvent.Raise("Error Message Event", 1, "CODE");
// sample 2 : create a Trace Message Event instance,
// fill it then raise from the event source
TraceMessageEvent messageEvent1 = new TraceMessageEvent();
messageEvent1.Message = "Costly Message";
myEventSource.Raise(messageEvent1 );
// sample 3 : static one line (which wraps the
// above code sequence)
TraceMessageEvent.Raise(myEventSource,
"Static One Line Message");
// sample 4 : static one line which is raised through
// the EventSource.Application EventSource.
TraceMessageEvent.Raise("Static One Line Message " +
"through the Application event source");
}
EIF uses a specific configuration file to link traces to the target library (event log, SQL, ...). See the demo configuration file for more details on
Log4Net (.NET) SupportLog4Net traces can be redirected to the viewer using the Sample Log4Net demo: // Create a logger for use in this class
// (Log4NetDemo.Form1)
private static ILog log = LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private void butLog_Click(object sender, EventArgs e)
{
// simple test
log.Info("Hello world");
// use an object as message (the object is
// displayed in the info panel)
log.Debug(log);
// exception test (the exception is displayed
// in the info panel)
Exception MyException = new Exception("my exception") ;
log.Error("Received exception",MyException);
}
Like for EIF, the Log4Net engine, the configuration file is used to link traces to the library.
Log4J (Java) SupportAs for Log4NET, Log4J traces can be redirected to the viewer using the Sample Log4J demo: Logger logger ; // Log4J logger
Category cat ; // Log4J category
// Initialize Log4J
PropertyConfigurator.configure("log4J.properties");
logger = Logger.getLogger("hello.world");
cat = Category.getInstance(JavaDemo.class);
// simple logger test. Log4J will prepare the trace
// and call the TraceTool appender.
logger.info("Hello world");
// Logger test with attached exception (displayed in info pane)
Exception e = new Exception("my exception") ;
logger.debug("Received exception",e);
// Category test with object value (displayed in info pane)
cat.debug(this);
Gdebug (Delphi) SupportSince the original idea of Sample Delphi code: SendDebug ('Hello world') ;
SendDebugEx ('Hello world', mtWarning);
Pocket PC DevelopmentThe C++ Framework works with classic C++ applications (like MFC) as well as with Pocket PC projects. The socket mode is used in this case. The traces are sent to the viewer in the development PC. The C# Framework is not yet compatible with the Compact Framework (should be done in the next release). Console ApplicationsThe four Frameworks can also be used for console applications. See the TTPipe demo from Michael Kramer in the .NET samples. This console application redirects the console output to the viewer, using the '|' pipe redirector: YourProg | TTPIPE [-t TabName] [-i Viewer Host IP Address] [-p Viewer Port]
Tracing ASP.NETThe problem with ASP.NET is that pages run under a service (IIS). The ASP code is then confined inside the service, and cannot send Windows messages to another process. The only way here is to use the second door: socket. You just need to modify the private void Page_Load(object sender, System.EventArgs e)
{
TTrace.Options.SendMode = SendMode.Socket ;
TTrace.Debug.Send (
"Page_Load " + Convert.ToString(TTrace.TraceCount));
}
Important: In socket mode, the viewer must be launched manually. In Windows message mode, the client Framework runs the viewer itself. The You can also modify the machine.config or web.config to include a custom To facilitate ASP.NET configuration, it's better to use one of the configuration files. .NET ConfigurationConfiguration of the
Sample App.config file: <configuration>
<configSections>
<section name="TraceTool"
type="TraceTool.ConfigSectionHandler, TraceTool" />
</configSections>
<TraceTool>
<param name="SendMode" value="winmsg" />
<Param name="sockethost" value="localhost" />
<param Name="SendProcessName" Value="false" />
<debug>
<param name="Enabled" value="true" />
<param name="IconIndex" value="24" />
</debug>
<warning></warning>
<error></error>
</TraceTool>
</configuration>
Plug-ins
You can extend the Using the Viewer
Catch System OutputDebugString Messages
To display the Display Multiple 'Tail' Content Files
To add a new "Tail" tab, select the Windows/Open Tail File... menu, then select the file you want to watch. Clipboard operations are allowed, but not exported, since traces are already stored in a file. The number of displayed lines is also specified in the Options menu. Watch Live Event Log Traces (Application, Security, System, or Other)
To add a new "event log" tab, select the Windows/Open Event Log... menu, then select the log you want to watch. New events are automatically added. Clipboard operations and XML export are allowed (the same format as Load Saved XML FileYou can save traces sent by the Framework, the License InformationYou are free to distribute the viewer and to incorporate the library in your product (commercial or not). The only thing you can't do is to sell the viewer (or a modified version) and the API as a tracing solution. For all others licenses informations, please refer to the Common Public License Version 1.0 (CPL) : http://www.opensource.org/licenses/cpl1.0.php Points of InterestFor those who want to have some examples on how to use the .NET Future Improvements
HistoryMay, 2008: Version 10.1 (only the C++ library goes to 10.2)
May, 2008: Version 10.1
March, 2008: Version 10.0
Nov, 2007: Version 9.0 (Major Update)One of the main update is the API redesign. Some incompatibilities are to be feared, but easy to fix ...
| ||||||||||||||||||||||||||||