[ Team LiB ] |
Recipe 6.1 Controlling Tracing Output inProduction CodeProblemMysterious bugs often appear at the client's site, even after the application is thoroughly tested. Most of the time these bugs are difficult, if not impossible, to reproduce on your development machine. Knowing this, you want an application with built-in instrumentation that's off by default but can easily be turned on when you need it. SolutionUse the Trace class for any tracing code that you might need to turn on after your application has been deployed. To turn on tracing at a client's site, provide the client with an application configuration file such as this one: <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.diagnostics> <switches> <add name="DatabaseSwitch" value="4"/> <!-- 4 == TraceLevel.Verbose --> </switches> <trace autoflush = "true" indentsize = "2"> <listeners> <add name = "MyListener" type = "System.Diagnostics.TextWriterTraceListener" initializeData = " MyFileName.log"/> </listeners> </trace> </system.diagnostics> </configuration> DiscussionAllowing tracing code to be enabled and used at a client site can be incredibly useful when debugging problems in release code. This technique is even more useful when the problem cannot easily be reproduced in-house. For this reason, it is—in some cases—a wise practice to use the Trace class instead of the Debug class when adding tracing code to your application. To control the trace output at a client site, you can use an XML config file. This XML file must have the same base name as the executable that is to use these switches, followed by an extension of .exe.config. For example, if the executable name were Accounting.exe, the configuration file would be named Accounting.exe.config. This file should be placed in the same directory as the executable Accounting.exe. The application configuration file always consists of the following two outer elements for diagnostic information: <configuration> <system.diagnostics> ... </system.diagnostics> </configuration> However, the configuration element may contain other child elements besides the system.diagnostics element. Within these elements, the switches and trace elements may be added. These two elements contain information specific to switches and listeners. If your code contains a TraceSwitch (as shown in the next example) or BooleanSwitch object—or any other type derived from the Switch class—you can control this object's trace level setting through the <switches> element in the configuration file: private static TraceSwitch ts = new TraceSwitch("DatabaseSwitch", "Only allow database transactions to be logged"); The <listeners> element shown in the Solution adds a new TraceListener derived object to the listeners collection. Any Trace or Debug statements will use this new listener. The switches element of the Solution can contain the three elements defined here:
Immediately after the switches tags in the solution are the trace tags, although the ordering of these tags is up to you. The trace tags can contain the following two optional attributes:
Within the trace tags are the listeners tags, which, in turn, can contain any of the following defined tags:
Regardless of whether your code defines TRACE and/or DEBUG, the code will attempt to access this file for switch initialization information if a class derived from Switch is instantiated. If you wish to prevent this behavior, place any code that instantiates a switch class inside of a method decorated with the ConditionalAttribute attribute: public class Traceable { BooleanSwitch DBSwitch = null; BooleanSwitch UISwitch = null; BooleanSwitch exceptionSwitch = null; [System.Diagnostics.ConditionalAttribute("TRACE")] public void EnableTracing( ) { DBSwitch = new BooleanSwitch("DatabaseSwitch", "Switch for database tracing"); UISwitch = new BooleanSwitch("UISwitch", "Switch for user interface tracing"); exceptionSwitch = new BooleanSwitch("ExceptionSwitch", "Switch for tracing thrown exceptions"); } } The ConditionalAttribute attribute prevents the switches from attempting to access the application configuration file when TRACE is undefined by preventing your application from calling the EnableTracing method. In addition to the application configuration file (MyApp.exe.config), there is also a machine.config file located in the directory %<runtime install path>%\CONFIG\. The configuration tags, and all of its containing elements may be placed in this file as well. However, doing so will enable these switches and listeners on a machine-wide level. This can cause applications that define their own listeners to behave strangely, especially if the listeners are duplicated. Additionally, the application will look for configuration information in the application configuration file first and the machine.config file second. The application configuration file and the machine configuration file are both case-sensitive. Be sure that your tag names and their attributes are in the correct case. However, the string assigned to the name attribute does not seem to be case-sensitive, while other strings assigned to attributes are case-sensitive. See AlsoSee the "Trace and Debug Settings Schema" topic in the MSDN documentation. |
[ Team LiB ] |