[ACCEPTED]-Turning tracing off via app.config-trace

Accepted answer
Score: 36

I agree with @Alex Humphrey's recommendation 76 to try using TraceSources. With TraceSources 75 you gain more control over how your logging/tracing 74 statements execute. For example, you could 73 have code like this:

public class MyClass1
{
  private static readonly TraceSource ts = new TraceSource("MyClass1");

  public DoSomething(int x)
  {
    ts.TraceEvent(TraceEventType.Information, "In DoSomething.  x = {0}", x);
  }
}

public class MyClass2
{
  private static readonly TraceSource ts = new TraceSource("MyClass2");

  public DoSomething(int x)
  {
    ts.TraceEvent(TraceEventType.Information, "In DoSomething.  x = {0}", x);
  }
}

The TraceSource.TraceEvent 72 call will automatically check the level 71 of the message (TraceEventType.Information) against 70 the configured level of the associated Switch 69 and will determine whether or not the message 68 should actually be written out.

By using 67 a differently named TraceSource for each 66 type, you can control the logging from those 65 classes individually. You could enable 64 MyClass1 logging or you could disable it 63 or you could enable it but have it log only 62 if the level of the message (TraceEventType) is 61 greater than a certain value (maybe only 60 log "Warning" and higher). At 59 the same time, you could turn logging in 58 MyClass2 on or off or set to a level, completely 57 independently of MyClass1. All of this 56 enabling/disabling/level stuff happens in 55 the app.config file.

Using the app.config 54 file, you could also control all TraceSources 53 (or groups of TraceSources) in the same 52 way. So, you could configure so that MyClass1 51 and MyClass2 are both controlled by the 50 same Switch.

If you don't want to have a 49 differently named TraceSource for each type, you 48 could just create the same TraceSource in 47 every class:

public class MyClass1
{
  private static readonly TraceSource ts = new TraceSource("MyApplication");

  public DoSomething(int x)
  {
    ts.TraceEvent(TraceEventType.Information, "In DoSomething.  x = {0}", x);
  }
}

public class MyClass2
{
  private static readonly TraceSource ts = new TraceSource("MyApplication");

  public DoSomething(int x)
  {
    ts.TraceEvent(TraceEventType.Information, "In DoSomething.  x = {0}", x);
  }
}

This way, you could make all 46 logging within your application happen at 45 the same level (or be turned off or go the 44 same TraceListener, or whatever).

You could 43 also configure different parts of your application 42 to be independently configurable without 41 having to go the "trouble" of 40 defining a unique TraceSource in each type:

public class Analysis1
{
  private static readonly TraceSource ts = new TraceSource("MyApplication.Analysis");

  public DoSomething(int x)
  {
    ts.TraceEvent(TraceEventType.Information, "In DoSomething.  x = {0}", x);
  }
}

public class Analysis2
{
  private static readonly TraceSource ts = new TraceSource("MyApplication.Analysis");

  public DoSomething(int x)
  {
    ts.TraceEvent(TraceEventType.Information, "In DoSomething.  x = {0}", x);
  }
}

public class DataAccess1
{
  private static readonly TraceSource ts = new TraceSource("MyApplication.DataAccess");

  public DoSomething(int x)
  {
    ts.TraceEvent(TraceEventType.Information, "In DoSomething.  x = {0}", x);
  }
}

public class DataAccess2
{
  private static readonly TraceSource ts = new TraceSource("MyApplication.DataAccess");

  public DoSomething(int x)
  {
    ts.TraceEvent(TraceEventType.Information, "In DoSomething.  x = {0}", x);
  }
}

With 39 your class instrumented this way, you could 38 make the "DataAccess" part of 37 your app log at one level while the "Analysis" part 36 of your app logs at a different level (of 35 course, either or both parts of your app 34 could be configured so that logging is disabled).

Here 33 is a part of an app.config file that configures 32 TraceSources and TraceSwitches:

<system.diagnostics>
  <trace autoflush="true"></trace>
  <sources>
    <source name="MyClass1" switchName="switch1">
      <listeners>
        <remove name="Default"></remove>
        <add name="console"></add>
      </listeners>
    </source>
    <source name="MyClass2" switchName="switch2">
      <listeners>
        <remove name="Default"></remove>
        <add name="console"></add>
      </listeners>
    </source>
  </sources>
  <switches>
    <add name="switch1" value="Information"/>
    <add name="switch2" value="Warning"/>
  </switches>
  <sharedListeners>
    <add name="console"
         type="System.Diagnostics.ConsoleTraceListener">
    </add>
    <add name="file"
         type="System.Diagnostics.TextWriterTraceListener"
         initializeData="trace.txt">
    </add>
  </sharedListeners>
</system.diagnostics>

As you can 31 see, you could configure a single TraceSource 30 and a single Switch and all logging would 29 occur with a single level of control (i.e. you 28 could turn all logging off or make it log 27 at a certain level).

Alternatively, you could 26 define multiple TraceSources (and reference 25 the corresponding TraceSources in your code) and 24 multiple Switches. The Switches may be 23 shared (i.e. multiple TraceSources can use 22 the same Switch).

Ultimately, by putting 21 in a little more effort now to use TraceSources 20 and to reference appropriately named TraceSources 19 in your code (i.e. define the TraceSource 18 names logically so that you can have the 17 desired degree of control over logging in 16 your app), you will gain significant flexibility 15 in the long run.

Here are a few links that 14 might help you with System.Diagnostics as 13 you go forward:

.net Diagnostics best practices?

Logging best practices

What&#39;s the best approach to logging?

Does the .Net TraceSource/TraceListener framework have something similar to log4net&#39;s Formatters?

In the links I posted, there 12 is often discussion of the "best" logging 11 framework. I am not trying to convince 10 you to change from System.Diagnostics. The 9 links also tend to have good information 8 about using System.Diagnostics, that is 7 why I posted them.

Several of the links I 6 posted contain a link to Ukadc.Diagnostics. This is a really 5 cool add on library for System.Diagnostics 4 that adds rich formatting capability, similar 3 to what you can do with log4net and NLog. This 2 library imposes a config-only dependency 1 on your app, not a code or reference dependency.

Score: 3

You don't turn off tracing globally this 10 way.

You have to
1) declare a switch and 9 set its value:

<switches>
  <add name="MySwitch" value="Information"/>
</switches>

2) associate this switch with 8 a TraceSource you use:

<sources>
  <source name="MySource" switchName="MySwitch"/>
</source>

So, whatever you write 7 via TraceSource named "MySource" is filtered 6 according to the switch value.

If you use 5 static methods like Trace.Write, I suppose, you cannot 4 use switches at all, because there is no 3 TraceSource to apply the filter.
If you 2 want to turn off tracing by static methods, just 1 remove all the listeners: <listeners> <clear/> </listeners>.

Score: 2

Check the state of dataSwitch whenever you 9 need to log, as per:

http://msdn.microsoft.com/en-us/library/aa984285%28v=VS.71%29.aspx

However, that is pretty 8 nasty, having to put those checks everywhere. Is 7 their a reason you don't want to simply 6 remove the TraceListener from the listeners collection 5 in app.config?

Apart from that, I'd investigate 4 using the .NET 2.0+ trace stuff which includes 3 TraceSource. The new(er) stuff offers a much higher 2 degree of configuration, and you might find 1 it's more suitable.

http://msdn.microsoft.com/en-us/library/ms228993.aspx

Score: 1

It´s the switchValue attribute of source 1 node:

<system.diagnostics>
<sources>
  <source name="System.ServiceModel"
          switchValue="Off"
          propagateActivity="true">
    <listeners>
      <add name="traceListener"
          type="System.Diagnostics.XmlWriterTraceListener"
          initializeData= "somePath" />
    </listeners>
  </source>
</sources>
<trace autoflush="true" />

Score: 1

Late joining with a quick footnote about 16 the app.config, in case this saves a couple 15 of days from the life of someone out there:

Assume 14 you have the startup (.exe) projectA containing 13 classA which makes use of projectB (.dll) containing 12 classB.

ClassB in turn makes use of a new 11 TraceSource("classB") instance. In order 10 to configure it you need to modify the app.config 9 or projectA. Tweaking the app.config of 8 projectB won't lead anywhere.

Also note that 7 the placement of the

<system.diagnostics>

Section inside app.config 6 seems to be causing problems if placed before 5 the section:

<configSections>

or after the section:

<userSettings>

At least 4 in my case, I was getting errors when I 3 attempted to place it in these locations 2 in the app.config of my project. The layout 1 that worked for me was:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
         ...config sections here if any...
     </configSections>
     <system.diagnostics>
         <trace autoflush="true"/>
         <sources>
             <source name="classB"
                 switchName="mySwitch"
                 switchType="System.Diagnostics.SourceSwitch" >
                 <listeners>
                    <clear/>
                    <add name="textwriterListener"
                         type="System.Diagnostics.TextWriterTraceListener"
                         initializeData="ClassBLog.txt"
                         traceOutputOptions="DateTime" />
                 </listeners>
             </source>
          </sources>
          <switches>
             <add name="mySwitch" value="Verbose" />
          </switches>
     </system.diagnostics>
     <runtime>
         ...runtime sections here if any...
     </runtime>
     <userSettings>
         ...usersettings sections here if any...
     </userSettings>
 </configuration>

More Related questions