none
WCF - define tracing in code RRS feed

  • Question

  • Hi,

    for WPF I can enable tracing like this:

            /// <summary>
            /// Configures the wpf text file logging for databinding
            /// </summary>
            private void ConfigureWpfLogging(string wpfLogFileName, SourceLevels wpfLogLevel)
            {
                // Configure WPF logging for databinding
                TraceListener textListener
                    = new TextWriterTraceListener(wpfLogFileName, "TextListener");
    
                SourceSwitch textListenerSwitch
                    = new SourceSwitch ("SourceSwitchDisplayName", "SourceSwitchDescription");
    
                textListenerSwitch.Level = wpfLogLevel;
    
                PresentationTraceSources.DataBindingSource.Listeners.Add(textListener);
                PresentationTraceSources.DataBindingSource.Switch = textListenerSwitch;
            }

    For WCF I am missing the equivalent of "PresentationTraceSources". Is tracing by code possible for WCF and if yes, what are the missing lines of code?

    Thank you!

    Wednesday, October 2, 2013 2:23 PM

Answers

  • Hi Torsten,

    >>But the dynamic change of an update of the source level was ignored.

    You might try track the TraceSource and create a funtion to change switchlevel when user wants. Refer: http://stackoverflow.com/questions/4041289/change-switchvalue-on-trace-listener-in-runtime

    Hope this helps.

    Best Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, October 7, 2013 11:09 AM
    Moderator
  • Hi,

    My suggestion is to use a custom TraceFilter which you apply to all listeners attached to the WCF TraceSources (i.e., "System.ServiceModel", "System.ServiceModel.MessageLogging"). Inside the TraceFilter's ShouldTrace() method you can then conditionally suppress tracing based on any information that's available to the app.

    Here is some sample code which you could use as a starting point. There is a static helper class which determines globally and once during the lifetime of an app whether tracing should be enabled or disabled:

    namespace WCF.Diagnostics
    {
        using System.Diagnostics;
    
        public static class WcfDiagnosticsHelper
        {
            private readonly static bool _shouldTraceWcf;
    
            static WcfDiagnosticsHelper()
            {
                // here, determine if WCF Tracing should be enabled or not
                // i.e., read some custom settings from App.config or the registry etc...
    
                _shouldTraceWcf = true;
            }
    
            internal static bool ShouldTraceWcf
            {
                get { return _shouldTraceWcf; }
            }
        }
    
        public class WcfTraceFilter : TraceFilter
        {
            public override bool ShouldTrace(TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage, object[] args, object data1, object[] data)
            {
                // In here, check the static 'ShouldTraceWcf' property as well as the name of the originating TraceSource
                if (source != null && source.StartsWith("System.ServiceModel") && !WcfDiagnosticsHelper.ShouldTraceWcf)
                    return false;
                return true;
            }
        }
    }

    In the App.config you'd configure the TraceFilter like this:

    <system.diagnostics>
      <sources>
        <source name="System.ServiceModel" propagateActivity="true" switchValue="Warning">
          <listeners>
            <add name="LocalXmlFile" initializeData="WcfTracing.svclog" type="System.Diagnostics.XmlWriterTraceListener">
              <filter type="WCF.Diagnostics.WcfTraceFilter, WCF_Custom_TraceFilter"/>
            </add>
          </listeners>
        </source>
      </sources>
    </system.diagnostics>

    **

    Please note that a similar behavior could be achieved by writing a custom Trace Switch. The main difference would be that a TraceSwitch is applied to a TraceSource, and a TraceFilter to a TraceListener. It would be slightly more involved, though.

    Monday, October 21, 2013 6:46 AM
  • Hi TorstenTiedt,

    >> Is tracing by code possible for WCF and if yes, what are the missing lines of code?

    Yes, you can enable WCF tracing programmatically, there are two workaround(through WMI; or use a custom switch for traces in app.config) you can refer in a blog at http://wcfpro.wordpress.com/2010/11/21/how-to-add-wcf-traces-programmatically/

    Moreover, you might also check a thread below on similar issue.

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/6a257576-7a19-48fc-9c1f-b8d8effb41fd/is-it-possible-to-programmatically-configure-wcf-logging

    Best Regards.


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Thursday, October 3, 2013 2:27 AM
    Moderator

All replies

  • Hi TorstenTiedt,

    >> Is tracing by code possible for WCF and if yes, what are the missing lines of code?

    Yes, you can enable WCF tracing programmatically, there are two workaround(through WMI; or use a custom switch for traces in app.config) you can refer in a blog at http://wcfpro.wordpress.com/2010/11/21/how-to-add-wcf-traces-programmatically/

    Moreover, you might also check a thread below on similar issue.

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/6a257576-7a19-48fc-9c1f-b8d8effb41fd/is-it-possible-to-programmatically-configure-wcf-logging

    Best Regards.


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Thursday, October 3, 2013 2:27 AM
    Moderator
  • Hi Haixia,

    I had a look at the blog entry you gave me:

    http://wcfpro.wordpress.com/2010/11/21/how-to-add-wcf-traces-programmatically/

    But the dynamic change of an update of the source level was ignored. I now came up with an own solution to change the source level during runtime, but although the source level of the source switch gets changed, it's new value is ignored.

    Here is my code (based on the blog):

        public class MySourceSwitch : SourceSwitch
        {
            public MySourceSwitch(string name)
                : base(name)
            {
                WcfSourceSwitches.SourceSwitches.Add(this);
            }
        }

    public static class WcfSourceSwitches { static WcfSourceSwitches() { WcfSourceSwitches.SourceSwitches = new List<MySourceSwitch>(); } public readonly static ICollection<MySourceSwitch> SourceSwitches; public static void ChangeSourceLevel(SourceLevels sourceLevel) { foreach (var sourceSwitch in WcfSourceSwitches.SourceSwitches) { sourceSwitch.Level = sourceLevel; } } }

    Whenever a source switch of type MySourceSwitch is created, it first has the source level of "Off". Using the static method ChangeSourceLevel of the class WcfSourceSwitches I can change the source level during runtime. Code runs fine, but no change in logging occurs.

    Any idea why? Maybe I must create new TraceSources instead of changing the SourceLevel only? If so, how can I access the existing TraceSources to copy their propertie values for the new TraceSources to create?

    Thank you!

    Torsten

    Friday, October 4, 2013 1:43 PM
  • Hi Torsten,

    >>But the dynamic change of an update of the source level was ignored.

    You might try track the TraceSource and create a funtion to change switchlevel when user wants. Refer: http://stackoverflow.com/questions/4041289/change-switchvalue-on-trace-listener-in-runtime

    Hope this helps.

    Best Regards.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, October 7, 2013 11:09 AM
    Moderator
  • Hi,

    thanks for link. Question: How to "keep track of the TraceSources" created? I saw that the TraceSource has a private static field collectoin called "traceSources". Sure, I probably can access it with reflection, but is there an official way to get a reference?

    Thank you,

    Torsten

    Wednesday, October 9, 2013 7:58 AM
  • Hi,

    My suggestion is to use a custom TraceFilter which you apply to all listeners attached to the WCF TraceSources (i.e., "System.ServiceModel", "System.ServiceModel.MessageLogging"). Inside the TraceFilter's ShouldTrace() method you can then conditionally suppress tracing based on any information that's available to the app.

    Here is some sample code which you could use as a starting point. There is a static helper class which determines globally and once during the lifetime of an app whether tracing should be enabled or disabled:

    namespace WCF.Diagnostics
    {
        using System.Diagnostics;
    
        public static class WcfDiagnosticsHelper
        {
            private readonly static bool _shouldTraceWcf;
    
            static WcfDiagnosticsHelper()
            {
                // here, determine if WCF Tracing should be enabled or not
                // i.e., read some custom settings from App.config or the registry etc...
    
                _shouldTraceWcf = true;
            }
    
            internal static bool ShouldTraceWcf
            {
                get { return _shouldTraceWcf; }
            }
        }
    
        public class WcfTraceFilter : TraceFilter
        {
            public override bool ShouldTrace(TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage, object[] args, object data1, object[] data)
            {
                // In here, check the static 'ShouldTraceWcf' property as well as the name of the originating TraceSource
                if (source != null && source.StartsWith("System.ServiceModel") && !WcfDiagnosticsHelper.ShouldTraceWcf)
                    return false;
                return true;
            }
        }
    }

    In the App.config you'd configure the TraceFilter like this:

    <system.diagnostics>
      <sources>
        <source name="System.ServiceModel" propagateActivity="true" switchValue="Warning">
          <listeners>
            <add name="LocalXmlFile" initializeData="WcfTracing.svclog" type="System.Diagnostics.XmlWriterTraceListener">
              <filter type="WCF.Diagnostics.WcfTraceFilter, WCF_Custom_TraceFilter"/>
            </add>
          </listeners>
        </source>
      </sources>
    </system.diagnostics>

    **

    Please note that a similar behavior could be achieved by writing a custom Trace Switch. The main difference would be that a TraceSwitch is applied to a TraceSource, and a TraceFilter to a TraceListener. It would be slightly more involved, though.

    Monday, October 21, 2013 6:46 AM