9

I recently read Chris Love's advice on using WCF Tracing to help with troubleshooting.
He turns on the tracing by adding new sections of XML to the app.config file and I have since seen similar recommendations here for the same technique.

However we don't really want to ship multiple app.config files.
And we definitely don't want our customers modifying them on production systems!

Is there a way that the various settings for WCF Tracing can be set up in the app.config, but the tracing is turned on/off from code?

Ideally I'd like my application to check the registry and only activate the tracing when a certain value was present.

Community
  • 1
  • 1
GrahamS
  • 9,980
  • 9
  • 49
  • 63

3 Answers3

11

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.

mthierba
  • 5,587
  • 1
  • 27
  • 29
  • Excellent answer. This is pretty close to what I need, but for some reason the log file still seems to grow even when I set `_shouldTraceWcf` to false. – GrahamS Nov 01 '11 at 17:20
  • That sounds strange. Could you post the `` section of your app.config? – mthierba Nov 01 '11 at 18:02
  • The `` was as you describe but with a second entry for `System.ServiceModel.MessageLogging` writing to a separate file. And a `` section turning on the message logging. Both used the same `TraceFilter` - the messagelogging one switched off (the file was created but stayed 0 bytes) but the `ServiceModel` was still populated. – GrahamS Nov 04 '11 at 12:44
  • I've abandoned work on this for now and just made it as easy as possible for the clients/field engineers to edit the app.config (using named `` entries so all they need to do is uncomment the `` entry in the `` section). I'm awarding you the bounty as you got me the closest to the solution. Thanks for your help. – GrahamS Nov 04 '11 at 12:46
2

Here is a link to a question about doing something similar. The guy that asked the question seemed to have some programmatic control over WCF tracing working, but not all. I don't if he ever got it working to his satisfaction or not.

WCF tracing in code does not follow MessageLogging settings

Maybe it will help you, maybe not.

Community
  • 1
  • 1
wageoghe
  • 27,390
  • 13
  • 88
  • 116
1

WCF tracing is plugging into the System.Diagnostics classes that have been in .NET for a long time. There is an API for anything done in xml. For example Create and Initialize Trace Listeners.

For the general overview scroll to the bottom of the Trace class documentation.

ErnieL
  • 5,773
  • 1
  • 23
  • 27