How to enable WCF traces programmatically?

Posted on November 21, 2010 by

2


Motivation

Enabling WCF traces requires updating the app.config and restarting the application.

Since production code usually does not run with the traces enabled, we open the traces only when we detect that something is wrong in the system and we need more information to detect the root cause.

The problem is that restarting the application (so that it will read the updated app.config file) will probably cause the problem we want to investigate to disappear.

Enabling WCF traces  programmatically without forcing restart will help us understand the root cause of communication problems on the fly.

Solution

There are two ways to open the WCF traces programmatically.

The first way, is through WMI, and its described in this post –

http://weblogs.asp.net/cibrax/archive/2007/07/03/wmi-support-in-wcf.aspx

The problem with this way is that it works only when there is a listening end point, i.e., it only works on the server side, which is not always enough to understand the entire scenario…

The second way, is to use a custom switch for traces in app.config.

In order to enable the WCF traces, we need to add the following lines to app.config:

<configuration>
    <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "c:\logs\client1.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
</configuration>

Enabling a custom switch is done the same, only we now add the switchType (which we will later implement in code)  and a shared listener:

<system.diagnostics>
    <trace autoflush="true"/>
    <sources>
      <source name="System.ServiceModel"
              switchValue ="Information"
              switchType="WCFSample.MySourceSwitch,

  Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

               propagateActivity="true">
        <listeners>
          <remove name="Default"/>
          <add name="traceListener"/>
        </listeners>
      </source>
</sources>
    <sharedListeners>
      <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "c:\logs\test.svclog" />
    </sharedListeners>
  </system.diagnostics>

The WCF tracing is implemented with

DiagnosticUtility and DiagnosticsTrace classes. These classes Initialize the tracing only for existing listeners in app.config, therefore we have to create a placeholder listener.We then set its tracing level to “Off”, and update it when necessary in code programmatically.

See http://msdn.microsoft.com/en-us/library/ms733025.aspx for more information about configuring tracing.

In code, we can control the trace level by implementing “MySourceSwitch” which inherits from SwitchValue and updates the level property.

 

public class WcfTracesController
{
   private static WcfTracesController Controller = null;
   private WcfTracesController()
   {
   }
   public delegate void TraceLevelController(SourceLevels level);
   public TraceLevelController LevelController;
   public static WcfTracesController Instance
   {
        get
        {
            if (Controller == null)
            {
                Controller = new WcfTracesController();
            }
            return Controller;
         }
    }
}
public class MySourceSwitch : SourceSwitch
{
    public MySourceSwitch(string name)
           : base("System.ServiceModel")
    {
         this.Level = SourceLevels.Information;
         WcfTracesController.Instance.LevelController = WcfTracesLevelController;
    }
    public void WcfTracesLevelController(SourceLevels level)
    {
          this.Level = level;
    }
}

And the way to change the trace level in code will be as follows:

WcfTracesController.Instance.LevelController(SourceLevels.Error);

Note:

WCF 4 adds support for ETW tracing as a production alternative for System.Diagnostics

Posted in: WCF traces