CSharpFeeds - All your C# feeds in one place.

Sponsors

Tuesday, January 23, 2007

Tracing and Message Logging in Windows Communication Foundation

by Keyvan Nayyeri via Keyvan Nayyeri on 1/23/2007 8:15:33 PM

Regular visitors can remember my post about Health Monitoring in ASP.NET 2.0 and my article about Writing a Custom Web Event Provider for ASP.NET 2.0.

Event and Exception Logging are common parts of enterprise applications in software world.  They show their importance when it comes to distributed systems.  Windows Communication Foundation as Microsoft infrastructure for building distributed systems provides excellent means to log everything and monitor your application both on server and client sides.

It's possible to enable End-To-End tracing and Message Logging for services and clients in Windows Communication Foundation.  Thankfully the process to enable these features is as easy as making some configurations in service or client.

Sample Service and Client

To check things I create a simple service and client.  My service provides one method which gets two integers and returns the result of their division.  Client uses this method to get two values from end user in a console application and shows the result.  I host my service in IIS to simplify the process.

You can guess that an exception will be thrown on server when I pass zero as second parameter to my method.  I use an if statement to catch this exception then throw an ArgumentOutOfRange exception.

So my service code is this:

using System;

using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

using System.Runtime.Serialization;

 

namespace SimpleService

{

    [ServiceContract()]

    public interface ISimpleService

    {

        [OperationContract]

        double Divide(int value1, int value2);

    }

 

    public class MyService : ISimpleService

    {

        public double Divide(int value1, int value2)

        {

            if (value2 == 0)

                throw new ArgumentOutOfRangeException(":-D");

            return (value1 / value2);

        }

    }

}

Initial configuration for my service is something like what you see below.

<?xml version="1.0"?>

<configuration>

  <system.serviceModel>

    <services>

      <service name="SimpleService.MyService"

              behaviorConfiguration="metadataSupport">

        <endpoint contract="SimpleService.ISimpleService"

                  binding="wsHttpBinding"/>

        <endpoint address="mex"

                  binding="mexHttpBinding"

                  contract="IMetadataExchange"/>

      </service>

    </services>

 

    <behaviors>

      <serviceBehaviors>

        <behavior name="metadataSupport">

          <serviceMetadata />

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

 

  <system.web>

    <compilation debug="false" />

  </system.web>

</configuration>

I generate proxy and configuration files for my client with svcutil command then use them in my console application.

static void Main(string[] args)

{

    Console.WriteLine("Enter value1:");

    int value1 = Convert.ToInt32(Console.ReadLine());

 

    Console.WriteLine("Enter value2:");

    int value2 = Convert.ToInt32(Console.ReadLine());

 

    Console.WriteLine();

 

    using (SimpleServiceClient proxy = new SimpleServiceClient())

    {

        Console.WriteLine(string.Format("{0} / {1} = {2}", value1.ToString(),

            value2.ToString(), proxy.Divide(value1, value2).ToString()));

 

        proxy.Close();

    }

    Console.ReadLine();

}

End-To-End Tracing

End-To-End Tracing can be enabled in <system.diagnostics /> element in Web.Config or App.Config files so it's not a part of <system.serviceModel /> where main configurations for WCF applications are declared.  <system.serviceModel /> has a <sources /> element as its child and <sources /> itself can have one or more <source /> elements.

In <source /> you define a name for your trace logging (it must be set to "Service.ServiceModel" and set a switchValue attribute to change the type of logging for service or client.  switchValue can be set to one of following values.  Each of them logs specific reports for you.

  • Critical
  • Error
  • Warning
  • Information
  • Verbose
  • ActivityTracing

You can define a set of listeners under <source /> element with <listeners /> element.  You listeners under <listeners /> element.

Each listener needs three attributes:

  • name: Defines a name for listener.
  • type: Refers to a .NET type where listener logic is defined.  System.Diagnostics.XmlWriterTraceListener is the most common type which is pre-defined in .NET and lets you to log things in XML files.  It's also possible to write into ETW logs.
  • initializeData: A file path where you expect your reports to be logged.

In addition to <sources /> element you can use <trace /> element and its autoflush attribute to flush traces to disk after each trace.

To see this in action I modify my service configuration file to enable tracing.  Note that it's possible to apply same configurations to client configuration in order to enable tracing on client side.  But keep in mind to choose a different file name for trace file for client to distinguish them later..

<?xml version="1.0"?>

<configuration>

  <system.serviceModel>

    <services>

      <service name="SimpleService.MyService"

              behaviorConfiguration="metadataSupport">

        <endpoint contract="SimpleService.ISimpleService"

                  binding="wsHttpBinding"/>

        <endpoint address="mex"

                  binding="mexHttpBinding"

                  contract="IMetadataExchange"/>

      </service>

    </services>

 

    <behaviors>

      <serviceBehaviors>

        <behavior name="metadataSupport">

          <serviceMetadata />

        </behavior>

      </serviceBehaviors>

    </behaviors>

  </system.serviceModel>

 

  <system.diagnostics>

    <sources>

      <source name="System.ServiceModel" switchValue="Error" propagateActivity="true">

        <listeners>

          <add name="xmlTrace" type="System.Diagnostics.XmlWriterTraceListener"

              initializeData="f:\Traces\MyTrace1.e2e" />

        </listeners>

      </source>

    </sources>

    <trace autoflush="true" />

  </system.diagnostics>

 

  <system.web>

    <compilation debug="false" />

  </system.web>

</configuration>

Here I check my Traces folder to make sure it has write access then launch my client and give 5 and 0 as two values.  Apparently I'll get an exception.

Console Client 

Exception

Alright, things are done!  I open MyTrace1.e2e file to see what's in it.

Trace  

Message Logging

In addition to tracing you can use message logging feature to log all messages that a WCF service sends or receives.  It helps you to diagnose your application.

Unlike tracing main configuration for message logging is under <system.serviceModel /> element.  <diagnostics /> element is where you add <messageLogging /> sub-element to enable and configure message logging.  By using some attributes you can configure message logging to only store latest N number of messages, entire message, malformed messages and ...

Name of message logging source is System.ServiceModel.MessageLogging which you can use to declare a listener for it and customize its default behavior.

In my example first I add a <diagnostic /> element to <system.serviceModel />:

<diagnostics>

  <messageLogging maxMessagesToLog="100"

          logEntireMessage="true"

          logMessagesAtServiceLevel="true"

          logMalformedMessages="true"

          logMessagesAtTransportLevel="true">

  </messageLogging>

</diagnostics>

Now I move xmlTrace listener to <sharedListeners /> to share it with message logging then add a new source for my message logging.  It will store logs into same file.

<system.diagnostics>

  <sources>

    <source name="System.ServiceModel" switchValue="Error" propagateActivity="true">

      <listeners>

        <add name="xmlTrace" />

      </listeners>

    </source>

    <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">

      <listeners>

        <add name="xmlTrace" />

      </listeners>

    </source>

  </sources>

  <sharedListeners>

    <add name="xmlTrace" type="System.Diagnostics.XmlWriterTraceListener"

        initializeData="f:\Traces\MyTrace2.e2e" />

  </sharedListeners>

  <trace autoflush="true" />

</system.diagnostics>

After running my client and giving two valid numbers and getting an output, I check MyTrace2.e2e file to see all messages that are sent or received by my service.

Message Log

Service Trace Viewer

SvcTraceViewer is a great tool that helps you (as a developer) to view tracing information and logged data and manage them easily because it's hard to work with XML files directly.  It comes with WinFX SDK and unfortunately I don't have it on this machine to give a snapshot.

email it!bookmark it!digg it!

Original Post: Tracing and Message Logging in Windows Communication Foundation

Subscribe

New Feed

Product Spotlight

Recently Updated Sources

Legal Note

The content of the postings is owned by the respective author. CSharpFeeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on CSharpFeeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.

Advertise with us