BlackWaspTM
Debugging
.NET 2.0+

Writing Debug and Trace Messages (2)

Complex software can be made easier to debug and monitor with the use of logging code. Such code outputs information about an application to the screen or to a location that can be examined during debugging or when the software is in a live environment.

Writing Messages Conditionally

When outputting warning or error messages you will want to only log the message when certain conditions are met. Although it is possible to surround the Debug methods with if statements or switch commands, this can reduce the readability of the code and draw attention to the logging rather than the program logic. In some cases the additional checks will also remain in the code when compiled without the DEBUG or TRACE symbols.

To remove these problems, the Debug and Trace classes provide versions of the Write and WriteLine methods that only output a message when an initial parameter is true. These are named WriteIf and WriteLineIf. For example, the following only logs a message if the variable named "loggingEnabled" is set to true:

Debug.WriteLineIf(loggingEnabled, "Application started", "Application");

Using Trace Listeners

The Debug and Trace classes both include a property named Listeners. This property holds a collection of trace listeners that receive the messages from the methods already described. The two classes share the collection so adding a listener to the Debug class' collection adds it to the Trace class too.

In the previous examples the collection has contained a single listener that showed the messages using the Output window. This is useful but in many situations a different type of listener is required. In the final section of this article we will set up a TextWriterTraceListener. This type of listener appends the messages to a text file. There are many other types of listener available and you can also implement your own custom types. However, these topics are beyond the scope of this article.

A TextWriterTraceListener can be created with a single line of code, passing the name of the file to use as the only parameter of its constructor. If the file does not exist, it will be created. Once the listener is instantiated, you may add it to the Listeners collection to enable it. As you are now working with files that should be flushed and closed correctly, you should call the Close method before exiting from your application.

The following code sample shows an example use of a listener. This code is in the Main method of a Windows Forms application. Before the main form is opened, a TextWriterTraceListener is initialised and added to the collection of listeners. When the application is about to exit, the Close method is called to ensure that all messages are written to the file correctly. Any messages logged throughout the operation of the software will be appended to the named file.

Debug.Listeners.Add(new TextWriterTraceListener(@"c:\temp\debug.log"));

Application.Run(new MainForm());

Debug.Close();

NB: Messages are passed to all of the listeners in the collection. It is therefore possible to view the messages in the Visual Studio debugger as well as writing to a log file.

30 December 2009