Creating a Custom Trace Listener for WCF

Monday, June 15, 2009

Introduction

We have been using WCF to consume a lot of 3rd party web services, and one of things we depend on when testing is being able to see the actual request and response that is being sent to and from the host.  This is expecially inportant in 3rd party services, because the service is essentially a black box in which there is no way to know what is going on except that you send it a request and you get a response back.  I posted how, out of the box, you can configure WCF to write the message to a trace xml file, but one of things about writing to a file is that if you or your testers do not have access to the web server where the file is being written then this is not going to work.

Solution

The way around this problem is to create a custom trace listener that catches the messages and does what ever you want.  Here is a simple sample.

Create a class that inherits from the TraceListiner class.

    1 using System.Diagnostics;

    2 

    3 namespace WcfTrace.Trace

    4 {

    5     public class WebTraceListener : TraceListener

    6     {

    7         public override void Write(string message)

    8         {

    9             //write you custom code here

   10             Debug.WriteLine(message);

   11         }

   12 

   13 

   14         public override void WriteLine(string message)

   15         {

   16             //write your custom code here

   17             Debug.WriteLine(message);

   18         }

   19     }

   20 }

The next thing to do is to wire up the custom class in the web.config (or app.config) so that when messages are created ,they caught by the custom trace listener class.  The config below is telling source messages to use the sharedListener named xml which the custom trace listener listed above.

  108   <system.diagnostics>

  109     <sources>

  110       <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">

  111         <listeners>

  112           <add name="xml" />

  113         </listeners>

  114       </source>

  115       <source name="System.ServiceModel.MessageLogging">

  116         <listeners>

  117           <add name="xml" />

  118         </listeners>

  119       </source>

  120     </sources>

  121     <sharedListeners>

  122       <add name="xml" type="WcfTrace.Trace.WebTraceListener,WcfTrace.Trace" />

  123     </sharedListeners>

  124   </system.diagnostics>

  125 

  126   <system.serviceModel>

  127     <diagnostics>

  128       <messageLogging

  129           logEntireMessage="true"

  130           logMalformedMessages="false"

  131           logMessagesAtServiceLevel="true"

  132           logMessagesAtTransportLevel="false"

  133           maxMessagesToLog="300000"

  134           maxSizeOfMessageToLog="200000"/>

  135     </diagnostics>

That's it.  Now when ever a web service call is made, the custom trace listener class is executed, passing it the trace messages.

comments powered by Disqus