How to track WCF errors and exception

This post is for those who are working with WCF and at times sulking because of errors which does not show up and who spends lots of time debugging what is going wrong with their service and client.

I was working with a WCF service and I came across a situation where my client application is trying to connect to service via proxy and client is waiting for the call to return and it never returns finally it times out. I was not having any clue what was happening. I had application level tracing which was not able to track anything. Finally I decided to enable WCF built in tracing!.

How to enable WCF Trace listener

By default Windows Communication Foundation (WCF) does not log messages. To enable message logging, you must add a trace listener to the System.ServiceModel.MessageLogging trace source and set attributes for the element in the configuration file. Lets see how to enable WCF logging. You can use WCF provided Configuration Editor Tool (SvcConfigEditor.exe) to configure these settings.

Basic Setting

<system.diagnostics>
  <sources>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
                 <add name="messages"
                 type="System.Diagnostics.XmlWriterTraceListener"
                 initializeData="c:\logs\messages.svclog" />
          </listeners>
      </source>
    </sources>
</system.diagnostics>

<system.serviceModel>
  <diagnostics>
    <messageLogging 
         logEntireMessage="true" 
         logMalformedMessages="false"
         logMessagesAtServiceLevel="true" 
         logMessagesAtTransportLevel="false"
         maxMessagesToLog="3000"
         maxSizeOfMessageToLog="2000"/>
  </diagnostics>
</system.serviceModel>
  • maxSizeOfMessageToLog is the message size in memory . This size can differ from the actual length of the message string that is being logged, and in many occasions is bigger than the actual size. As a result, messages may not be logged. So consider this situation and set the value of maxSizeOfMessageToLog appropriately.
  • logMessagesAtServiceLevel This boolean value is for logging messages at service level. Messages logged at this layer are about to enter (on receiving) or leave (on sending) user code. By default all messages at the service level are logged. Infrastructure messages (transactions, peer channel, and security) are also logged at this level, except for Reliable Messaging messages. On streamed messages, only the headers are logged. In addition, secure messages are logged decrypted at this level.
  • logMessagesAtTransportLevel This boolean value is for logging messages at transport level. Messages logged at this layer are ready to be encoded or decoded for or after transportation on the wire. By default all messages at the transport layer are logged. All infrastructure messages are logged at this layer, including reliable messaging messages. On streamed messages, only the headers are logged. In addition, secure messages are logged as encrypted at this level, except if a secure transport such as HTTPS is used.

Where to apply the log

You can apply the configuration on both service side and client side configuration file. You can analyse the log file which will be created after you run the service. Here if you are using the trace listener as-is then it will create a log file at “c:\logs\messages.svclog”. you can change the file location as you like.

When you are using logging in debugging environment , and you are using WCF trace sources, set the switchValue to Information or Verbose, along with ActivityTracing. To enhance debugging, you should also add an additional trace source (System.ServiceModel.MessageLogging) to the configuration to enable message logging. Notice that the switchValue attribute has no impact on this trace source.

You can set the switchValue attribute to Information in all the previously mentioned cases, When you set the switchValue attribute to Information, it will log all messages. A recommended configuration is as shown below.

<configuration>
 <system.diagnostics>
  <sources>
    <source name="System.ServiceModel" switchValue="Information,
 ActivityTracing"
            propagateActivity="true" >
      <listeners>
        <add name="xml"/>
      </listeners>
    </source>
    <source name="System.ServiceModel.MessageLogging">
      <listeners>
        <add name="xml"/>
      </listeners>
    </source>
    <source name="myUserTraceSource" switchValue="Information, ActivityTracing">
      <listeners>
        <add name="xml"/>
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add name="xml"
         type="System.Diagnostics.XmlWriterTraceListener"
               initializeData="C:\logs\Traces.svclog" />
  </sharedListeners>
 </system.diagnostics>

 <system.serviceModel>
  <diagnostics wmiProviderEnabled="true">
      <messageLogging 
           logEntireMessage="true" 
           logMalformedMessages="true"
           logMessagesAtServiceLevel="true" 
           logMessagesAtTransportLevel="true"
           maxMessagesToLog="3000" 
       />
  </diagnostics>
 </system.serviceModel>
</configuration>

When you are using logging in production environment, and you are using WCF trace sources, set the switchValue to Warning. If you are using the WCF System.ServiceModel trace source, set the switchValue attribute to Warning and the propagateActivity attribute to true. If you are using a user-defined trace source, set the switchValue attribute to Warning, ActivityTracing. If you do not fell like there will be any performance hit, you can set the switchValue attribute to Information in all the previously mentioned cases, When you set the switchValue attribute to Information, it will log all messages which will be a fairly large amount of data and this is why it should be avoided if you feel it will cause you performance hit. A recommended configuration is as shown below.

<configuration>
 <system.diagnostics>
  <sources>
    <source name="System.ServiceModel" switchValue="Warning"
            propagateActivity="true" >
      <listeners>
        <add name="xml"/>
      </listeners>
    </source>
    <source name="myUserTraceSource"
            switchValue="Warning, ActivityTracing">
      <listeners>
        <add name="xml"/>
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add name="xml"
         type="System.Diagnostics.XmlWriterTraceListener"
               initializeData="C:\logs\Traces.svclog" />
  </sharedListeners>
 </system.diagnostics>

<system.serviceModel>
  <diagnostics wmiProviderEnabled="true">
  </diagnostics>
 </system.serviceModel>
</configuration>

After enabling WCF level logging you will come to know what is wrong in your system. When you have the type of exception that you have, its much simpler to fix it. :)

Delphi how to check if you have read permission on a directory

It seems to be difficult to check the read permission on a directory in Delphi 2009. Here we will see how to find the read permission in an alternate way. Continue reading

Libish Varghese Jacob

Libish Varghese JacobI am currently working as a lead engineer in one of the leading wind turbine manufacturing firm. I have wide range of interests and getting my hands dirty in technology is one among them. I use this platform primarily as my knowledge base. I also use this platform to share my experience and experiments so that it might help someone who is walking the way I already did. The suggestions expressed here are the best to my knowledge at the time of writing and this may not necessarily be the best possible solution. I would pretty much appreciate if you could comment on it to bring into my notice on what could have been done better.