System.Diagnostics TraceSource
CleanCode.Diagnostics StructuredTraceSource
Namespace: CleanCode.Diagnostics
Assembly: CleanCode (in CleanCode.dll) Version: 1.2.3.0 (1.2.03)
public class StructuredTraceSource : TraceSource
The StructuredTraceSource operates just like a standard TraceSource but it adds a few methods that help monitor the structure of your application. Use TraceEnter and TraceLeave at the start and conclusion, respectively, of each method you wish to trace. These methods not only output a trace event with a unique ID corresponding to the enter or leave, but also increment or decrement the indentation automatically, so that you may visually see nested calls in your output log.
For methods that are event handlers, use TraceEnterEventHandler() and TraceLeaveEventHandler() instead, to get additional output related to the control that generated the event. The log message will include the name of the control, its type, and its display label. Say, for example, you have a Button control in your Windows Form application whose name is "goButton" and whose Text property is simply "Go". A call to TraceEnterEventHandler will generate this log message:
ENTER Event Handler: goButton Button 'Go'
The act of instantiating a StructuredTraceSource itself generates one or two log events. If it is the very first StructuredTraceSource used by any file or library in your application, it firsts emits a session marker (a string of selectable length of a repeated, selectable character). This allows you to scan your output log and easily determine where one session ends and the next begins. (This does, of course, assume that only one instance of your application is running on any given machine.) Besides the session marker emitted only by the first instantiation, every instantiation of StructuredTraceSource records a log event of its own creation with a unique event ID (the CreateEventId).
Each of the additional trace events detailed above are output with a trace event type of Information. Note that the standard TraceInformation() method always outputs events with an event ID of 0; if you wish to preserve that convention, you may set the various event IDs to 0 via properties of this class.
One common pitfall for users is not to flush the output periodically with the Flush method. Without that you may get no output at all. So StructuredTraceSource changes the default static AutoFlush property to true. If you would rather not have auto-flush enabled for performance reasons, you may set it back to false after instantiating a StructuredTraceSource.
Another common pitfall involves initialization. As mentioned, just instantiating a StructuredTraceSource emits a trace event. If you wish to adjust any default settings of a given TraceListener -- either standard TraceOutputOptions or other settings, such as those selectable in an AlignedTextWriterTraceListener -- those should be set before any StructuredTraceSource instance is created. In practice that could be done in one of two ways: ensure that whenever you instantiate a StructuredTraceSource make sure it is in an object constructor, not in a static declaration. That would work fine if you never use external libraries, but you do not have control over how some external library may or may not have done this. The better approach, therefore, is to use a static constructor in your main application that makes your default changes, then instantiates a StructuredTraceSource, as in:
static MainForm() { AlignedTextWriterTraceListener.EventIdLength = 0; AlignedTextWriterTraceListener.TraceEventTypeLength = 0; tracer = new StructuredTraceSource("main"); }
Besides the description here, I have also published an article discussing the practical uses of this TraceListener -- Exploring Secrets of .NET Diagnostics -- available on the DevX online magazine.
Those classes within the CleanCode libraries that are instrumented with StructuredTraceSource diagnostics each have a paragraph in the API that indicates "This class is instrumented with a StructuredTraceSource for diagnostic output. Its key name is xyz." The key name is what you would use in the diagnostic section of your configuration file to enable the trace and the name to look for in the diagnostic output for each relevant trace line.
Since CleanCode 0.9.20.