Showing posts with label Diagnostic. Show all posts
Showing posts with label Diagnostic. Show all posts

Dec 18, 2008

TraceSource

In my post How to control whether to output Trace, I discussed how to output behavior of Trace object. We can control destination with the system.diagnostics.trace section, and control the when to output Trace by using listener's filter or using switch.

But .net offer a better object to replace Trace object, that is TraceSource. It explicitly explicitly works with listener and switch to give user a better control. Here is an article on this issue. Below is some demo code. For new application, we should only use TraceSource object instead of Trace. Please note that now you can use both Listner filter and switch to control whether to output. The reason to use TraceSource over Trace is that TraceSource is instance object, Trace is a static object. You may use different TraceSource to trace different component. This is especially useful to third party component so that their trace may be independent of user's trace. Here is another artical Extending System.Diagnostics

class Program
{
    public static TraceSource MasterTraceSource = new TraceSource("TraceSourceApp");

    static void Main(string[] args)
    {
        Trace.WriteLine("program started...");
        Trace.Assert(1 != 1, "something wrong");
        // 
        MasterTraceSource.TraceInformation("Trace information");
        MasterTraceSource.TraceEvent(TraceEventType.Error, 1, "Error message.");
        MasterTraceSource.TraceEvent(TraceEventType.Verbose, 2, "Warning message.");
        MasterTraceSource.Close();
        return;
    }

} 

  
    
      
        
      
      
    
  



  

How to contro whether output Trace

We already know Listner affect Trace object's output destination. But that is only an aspect of behavior, another aspect is whether the message should be output. The control this we can test a configurable switch's value to determine whether we should output the message. But we need to manually Test the the switch, or we need to write a helper class to wrap the test code. Here is the code.

class Program
{
    static TraceSwitch switch1 = new TraceSwitch("global", "global switch");

    static void Main(string[] args)
    {
        Trace.WriteLine(switch1.Level);
        Trace.Assert(2 == 1, "error message is here, because assert fail(condition is false)");

        if (switch1.TraceError)
        {
            Trace.TraceError("An error happend");
        }

        if (switch1.TraceInfo)
        {
            Trace.TraceInformation("just for your information");
        }

        if (switch1.TraceWarning)
        {
            Trace.TraceWarning("just a warning");
        }
    }
}

We can also use another filter feature of Listener, without using switch1.


  
    
  

Trace.Assert

In nunit or other test framework, we have Assert object to test whether result is as expected. If assert is false, then en exception is through. Trace.Assert is provide similar function, but for different purpose. It is for diagnostic. When assert is false, it output the error message to a listener. There is default listener in .net, which is DefaultTraceListener An instance of this class is automatically added to the Debug..::.Listeners and Trace..::.Listeners collections. Explicitly adding a second DefaultTraceListener causes the message also show in the debugger output window and the messageboxe for asserts. The DefaultTraceListner looks like throwing an exception, but it is not actually an exception, it is for user interaction and there is no exception to catch at all. If you remove the DefaultTraceListner like below, you will not see this output, and the execution will continue.



<configuration>
  <system.diagnostics>
    <trace>
      <listeners>
        <clear/>
        <add name="text" />
      </listeners>
    </trace>
    <sharedListeners>
      <add name="text" type="System.Diagnostics.TextWriterTraceListener" initializeData="textfileListner.log" />
    </sharedListeners>
  </system.diagnostics>
</configuration>

Sep 20, 2007

Best practice of using Trace and Debug

class Program
            {

            static void Main(string[] args)
            {
            Trace.WriteLine("program started...");
            Trace.Assert(1 != 1, "something wrong");
            //
            MasterTraceSource.TraceInformation("Trace information");
            MasterTraceSource.TraceEvent(TraceEventType.Error, 1, "Error message.");
            MasterTraceSource.TraceEvent(TraceEventType.Verbose, 2, "Warning message.");
            MasterTraceSource.Close();
            return;
            }



            private static TraceSource mySource = new TraceSource("TraceSourceApp");
            public static TraceSource MasterTraceSource
            {
            get
            {
            return mySource;
            }
            }
            }

            

            <?xml version="1.0" encoding="utf-8" ?>
            <configuration>
            <system.diagnostics>
            <sources>
            <!--
            "TraceSourceApp" is the name of TraceSource, new TraceSource("TraceSourceApp")
            switch name reference the name in source switch, it controls whether send
            the information to listners
            -->
            <source name="TraceSourceApp" switchName="sourceSwitch" switchType="System.Diagnostics.SourceSwitch">
            <listeners>
            <add name="consoleListner" />
            <add name="textfileListner"/>
            <remove name="Default"/>
            </listeners>
            </source>
            </sources>

            <trace autoflush="true" indentsize="4">
            <listeners>
            <add name="consoleListner" />
            <remove name="Default" />
            </listeners>
            </trace>

            <switches>
            <add name="sourceSwitch" value="Verbose"/>
            </switches>

            <sharedlisteners>
            <add name="consoleListner" type="System.Diagnostics.ConsoleTraceListener">
            <!--filter is optional, it controls whether to output info to underlining datasource-->
            <filter type="System.Diagnostics.EventTypeFilter" initializeData="Error"/>
            </add>
            <add name="textfileListner" type="System.Diagnostics.TextWriterTraceListener" initializeData="textfileListner.log">
            <filter type="System.Diagnostics.EventTypeFilter" initializeData="Verbose"/>
            </add>
            </sharedListeners>



            </system.diagnostics>
            </configuration>

When you enable system.web.trace enabled ="true" requestLimit="20" writeToDiagnosticsTrace ="true " pageOutput ="false", the trace not only ouput to page or trace.axd, it will be also ouput system.diagnostic.trace listner. But it is much simpler.