How to: Use TraceSource and Filters with Trace Listeners

Note

This article is specific to .NET Framework. It doesn't apply to newer implementations of .NET, including .NET 6 and later versions.

One of the new features in the .NET Framework version 2.0 is an enhanced tracing system. The basic premise is unchanged: tracing messages are sent through switches to listeners, which report the data to an associated output medium. A primary difference for version 2.0 is that traces can be initiated through instances of the TraceSource class. TraceSource is intended to function as an enhanced tracing system and can be used in place of the static methods of the older Trace and Debug tracing classes. The familiar Trace and Debug classes still exist, but the recommended practice is to use the TraceSource class for tracing.

This topic describes the use of a TraceSource coupled with an application configuration file. It is possible, although not recommended, to trace using a TraceSource without the use of a configuration file. For information on tracing without a configuration file, see How to: Create and Initialize Trace Sources.

To create and initialize your trace source

  1. The first step to instrumenting an application with tracing is to create a trace source. In large projects with various components, you can create a separate trace source for each component. The recommended practice is to use the application name for the trace source name. This will make it easier to keep the different traces separate. The following code creates a new trace source (mySource) and calls a method (Activity1) that traces events. The trace messages are written by the default trace listener.

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    namespace TraceSourceApp
    {
        class Program
        {
            private static TraceSource mySource =
                new TraceSource("TraceSourceApp");
            static void Main(string[] args)
            {
                Activity1();
                mySource.Close();
                return;
            }
            static void Activity1()
            {
                mySource.TraceEvent(TraceEventType.Error, 1,
                    "Error message.");
                mySource.TraceEvent(TraceEventType.Warning, 2,
                    "Warning message.");
            }
        }
    }
    

To create and initialize trace listeners and filters

  1. The code in the first procedure does not programmatically identify any trace listeners or filters. The code alone results in the trace messages being written to the default trace listener. To configure specific trace listeners and their associated filters, edit the configuration file that corresponds to the name of your application. In this file, you can add or remove a listener, set the properties and filter for a listener, or remove listeners. The following configuration file example shows how to initialize a console trace listener and a text writer trace listener for the trace source that is created in the preceding procedure. In addition to configuring the trace listeners, the configuration file creates filters for both of the listeners and creates a source switch for the trace source. Two techniques are shown for adding trace listeners: adding the listener directly to the trace source and adding a listener to the shared listeners collection and then adding it by name to the trace source. The filters identified for the two listeners are initialized with different source levels. This results in some messages being written by only one of the two listeners.

    <configuration>
      <system.diagnostics>
        <sources>
          <source name="TraceSourceApp"
            switchName="sourceSwitch"
            switchType="System.Diagnostics.SourceSwitch">
            <listeners>
              <add name="console"
                type="System.Diagnostics.ConsoleTraceListener">
                <filter type="System.Diagnostics.EventTypeFilter"
                  initializeData="Warning"/>
              </add>
              <add name="myListener"/>
              <remove name="Default"/>
            </listeners>
          </source>
        </sources>
        <switches>
          <add name="sourceSwitch" value="Warning"/>
        </switches>
        <sharedListeners>
          <add name="myListener"
            type="System.Diagnostics.TextWriterTraceListener"
            initializeData="myListener.log">
            <filter type="System.Diagnostics.EventTypeFilter"
              initializeData="Error"/>
          </add>
        </sharedListeners>
      </system.diagnostics>
    </configuration>
    

To change the level at which a listener writes a trace message

  1. The configuration file initializes the settings for the trace source at the time the application is initialized. To change those settings you must change the configuration file and restart the application or programmatically refresh the application using the Trace.Refresh method. The application can dynamically change the properties set by the configuration file to override any settings specified by the user. For example, you might want to assure that critical messages are always sent to a text file, regardless of the current configuration settings.

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    namespace TraceSourceApp
    {
        class Program
        {
            private static TraceSource mySource =
                new TraceSource("TraceSourceApp");
            static void Main(string[] args)
            {
                Activity1();
    
                // Change the event type for which tracing occurs.
                // The console trace listener must be specified
                // in the configuration file. First, save the original
                // settings from the configuration file.
                EventTypeFilter configFilter =
                    (EventTypeFilter)mySource.Listeners["console"].Filter;
    
                // Then create a new event type filter that ensures
                // critical messages will be written.
                mySource.Listeners["console"].Filter =
                    new EventTypeFilter(SourceLevels.Critical);
                Activity2();
    
                // Allow the trace source to send messages to listeners
                // for all event types. This statement will override
                // any settings in the configuration file.
                mySource.Switch.Level = SourceLevels.All;
    
                // Restore the original filter settings.
                mySource.Listeners["console"].Filter = configFilter;
                Activity3();
                mySource.Close();
                return;
            }
            static void Activity1()
            {
                mySource.TraceEvent(TraceEventType.Error, 1,
                    "Error message.");
                mySource.TraceEvent(TraceEventType.Warning, 2,
                    "Warning message.");
            }
            static void Activity2()
            {
                mySource.TraceEvent(TraceEventType.Critical, 3,
                    "Critical message.");
                mySource.TraceInformation("Informational message.");
            }
            static void Activity3()
            {
                mySource.TraceEvent(TraceEventType.Error, 4,
                    "Error message.");
                mySource.TraceInformation("Informational message.");
            }
        }
    }
    

See also