locked
Apply Custom Trace Messages to System.ServiceModel tracing? RRS feed

  • Question

  • Hello.

    does anybody know if it is possible to apply custom tracemassages to the Activity / messages Tracing machanism of WCF? The Idea behind this is to use the ScvLogViewer-Tool to display our custom tracing statements together with the WCF Trace.

    Thanks for any replys
    Marcus
    Friday, August 31, 2007 8:49 AM

Answers

  • hi,

    no problem fx.:

     

       

    Code Snippet

    public class StreamImpl : IStreamingDemo 
    {
            static TraceSource ts = new TraceSource("System.ServiceModel");

     

            public void Stream_Clemens_test(MyMessageContract msg)
            {

                ts.TraceEvent(TraceEventType.Start, 0, "in da game now");
                ts.TraceEvent(TraceEventType.Information, 0, "create file");
                FileStream stm = new FileStream("ClemensVasters_300.wmv", FileMode.Create);
                ts.TraceEvent(TraceEventType.Stop, 0, "after create file");
               
                Trace.CorrelationManager.ActivityId = Guid.NewGuid();

                ts.TraceEvent(TraceEventType.Start, 0, "new activity");

                Guid currentActivity = Trace.CorrelationManager.ActivityId;
                Guid newActivity = Guid.NewGuid();
                ts.TraceTransfer(0, "simulate transporting to another activity", newActivity);
                Trace.CorrelationManager.ActivityId = newActivity;
                ts.TraceEvent(TraceEventType.Information, 0, "and we're writing the file");
                int i;
                do
                {

                    byte[] buffer = new byte[1024];
                    i = msg.body.Read(buffer, 0, buffer.Length);
                    stm.Write(buffer, 0, i);
                }
                while (i > 0);
                stm.Close();

                Trace.CorrelationManager.ActivityId = currentActivity;
                ts.TraceEvent(TraceEventType.Stop, 0, "we did it, streaming done now");

    ......

    .......

     

     

    so it starts with "connecting" to the same tracesource at wcf uses default...

    Code Snippet
    new TraceSource("System.ServiceModel");

     

    or

    Code Snippet
    new TraceSource("System.ServiceModel.MessageLogging");

     

     

     

    hth, allan

     

     

    Saturday, September 1, 2007 7:15 AM

All replies

  • hi,

    no problem fx.:

     

       

    Code Snippet

    public class StreamImpl : IStreamingDemo 
    {
            static TraceSource ts = new TraceSource("System.ServiceModel");

     

            public void Stream_Clemens_test(MyMessageContract msg)
            {

                ts.TraceEvent(TraceEventType.Start, 0, "in da game now");
                ts.TraceEvent(TraceEventType.Information, 0, "create file");
                FileStream stm = new FileStream("ClemensVasters_300.wmv", FileMode.Create);
                ts.TraceEvent(TraceEventType.Stop, 0, "after create file");
               
                Trace.CorrelationManager.ActivityId = Guid.NewGuid();

                ts.TraceEvent(TraceEventType.Start, 0, "new activity");

                Guid currentActivity = Trace.CorrelationManager.ActivityId;
                Guid newActivity = Guid.NewGuid();
                ts.TraceTransfer(0, "simulate transporting to another activity", newActivity);
                Trace.CorrelationManager.ActivityId = newActivity;
                ts.TraceEvent(TraceEventType.Information, 0, "and we're writing the file");
                int i;
                do
                {

                    byte[] buffer = new byte[1024];
                    i = msg.body.Read(buffer, 0, buffer.Length);
                    stm.Write(buffer, 0, i);
                }
                while (i > 0);
                stm.Close();

                Trace.CorrelationManager.ActivityId = currentActivity;
                ts.TraceEvent(TraceEventType.Stop, 0, "we did it, streaming done now");

    ......

    .......

     

     

    so it starts with "connecting" to the same tracesource at wcf uses default...

    Code Snippet
    new TraceSource("System.ServiceModel");

     

    or

    Code Snippet
    new TraceSource("System.ServiceModel.MessageLogging");

     

     

     

    hth, allan

     

     

    Saturday, September 1, 2007 7:15 AM
  • Hello.
    When I do something similar, namely:

    TraceSource ts = new TraceSource("System.ServiceModel");
               ts.TraceEvent(TraceEventType.Information, 1, "Just testing");

     I get the following exception

    Unhandled Exception: System.Configuration.ConfigurationErrorsException: 'propagateActivity' is not a valid configuration
     attribute for type 'System.Diagnostics.TraceSource'.

    Must I define a class derived from TraceSource that supports the 'propageteActivity" attribute?

    Thanks
    Pedro Felix


    Thursday, September 6, 2007 12:51 PM
  • Yes I get that all the time, don't know why, apparently it's not supported. Just remove the propagateActivity from the config file then, that works for me.

     

    About the custom trace messages, there is even an easier way you can integrate with the existing wcf trace log.

     

    start the svcconfigeditor, under diagnostic->sources, add you own source fx. "mysrc", then go up to the diagnostic->listeners, choose either/both "ServiceModelMessageLoggingListener" and or "ServiceModelTraceListener" and then add you new source "mysrc" .

     

    you would then use your source "mysrc" with TraceSource class as usual.

     

    hth, Allan

    Monday, September 17, 2007 9:11 AM
  • Hello.

    Thanks for the reply. I used a different solution: a class derived from TraceSource that supports (and ignores) the "propagateActivity" attribute.

    Here is the source code:

     

    class MyTraceSource : TraceSource
        {
            public MyTraceSource(string name) : base(name) { }

            protected override string[] GetSupportedAttributes()
            {
                string[] sa = base.GetSupportedAttributes();
                if (sa == null) return new string[] { "propagateActivity" };
                string[] sa2 = new string[sa.Length + 1];
                sa2[0] = "propagateActivity";
                Array.Copy(sa, 0, sa2, 1, sa.Length);
                return sa;
            }

            public void TraceMessage(ref Message msg, string source)
            {
                // Create a duplicate Message (Messages can be read only once)
                MessageBuffer mb = msg.CreateBufferedCopy(Int16.MaxValue);
                msg = mb.CreateMessage();
                Message msg2 = mb.CreateMessage();

     

                // The the XmlWriter where to put the trace information
                MemoryStream ms = new MemoryStream();
                XmlWriter xw = XmlWriter.Create(ms);

     

                // Write the MessageLogTraceRecord begin tag
                xw.WriteStartElement("MessageLogTraceRecord","http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace");
                xw.WriteAttributeString("Time",DateTime.Now.ToLongTimeString());
                xw.WriteAttributeString("Source",source);
                xw.WriteAttributeString("Type",msg.GetType().ToString());

     

                // Write the message
                msg2.WriteMessage(xw);

     

                // Write the MessageLogTraceRecord end element
                xw.WriteEndElement();

     

                // Finish the job
                xw.Flush();
                ms.Position = 0;
                XPathDocument xpd = new XPathDocument(ms);
                base.TraceData(TraceEventType.Information, 1, xpd.CreateNavigator());
                this.Flush();
            }


        }

     

    Monday, September 17, 2007 11:10 PM
  • The intent of this feature is not to overuse and abuse the name 'System.ServiceModel' for your source. Instead, use the collection to add your own, independent trace source that just happens to emit traces to the same file. Config looks like this:

     

    Code Snippet

    <system.diagnostics>

    <sources>

    <source name="System.ServiceModel" switchValue="Verbose,ActivityTracing"

    propagateActivity="true">

    <listeners>

    <add name="ServiceModelTraceListener" />

    </listeners>

    </source>

    <source name="MyTraceSource" switchValue="Verbose">

    <listeners>

    <add name="ServiceModelTraceListener" />

    </listeners>

    </source>

    </sources>

    <sharedListeners>

    <add initializeData="app_tracelog.svclog"

    type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

    name="ServiceModelTraceListener" traceOutputOptions="Timestamp"/>

    </sharedListeners>

    <trace autoflush="true" />

    </system.diagnostics>

     

     

    then, just instantiate your TraceSource and trace away:

    Code Snippet

    TraceSource ts = new TraceSource("MyTraceSource", SourceLevels.Warning);

    ts.TraceEvent(TraceEventType.Information, 1, "hello, world!");

     

     

    This way, you can have many writers sharing one trace file, all with independent, identifiable sources. It's why ServiceModel used System.Diagnostics instead of building it's own story.

    • Proposed as answer by mcjoxp Tuesday, December 28, 2010 11:34 PM
    Monday, September 17, 2007 11:31 PM
  • Hello.

    Thanks for the post. I agree that the solution that you propose is a better one. The only negative aspect is that it implies a change in the config file. When I tought of my solution, I was aiming for something that didn't required any custom configuration.

     

    Thanks

    Pedro Felix

     

    Tuesday, September 18, 2007 9:31 AM
  • Hi Scott,

     

     Allan-Nielsen wrote:

    About the custom trace messages, there is even an easier way you can integrate with the existing wcf trace log.

     

    start the svcconfigeditor, under diagnostic->sources, add you own source fx. "mysrc", then go up to the diagnostic->listeners, choose either/both "ServiceModelMessageLoggingListener" and or "ServiceModelTraceListener" and then add you new source "mysrc" .

     

    you would then use your source "mysrc" with TraceSource class as usual.

     

    I believe along the lines that this was the intention of my post, but yes "abusing" the system.servicemodel is bad, I agree on that.

     

    Adding your own trace source and have it integrated with the existing wcf logs is such an overlooked feature.

     

    Allan

    Tuesday, September 18, 2007 11:18 AM