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.
Tracing is not enabled by default. To activate tracing, you must create a trace listener and set a trace level other than "Off" for the selected trace source in configuration; otherwise, WCF does not generate any traces. If you do not specify a listener, tracing is automatically disabled.
Windows Communication Foundation (WCF) does not log messages by default. To activate message logging, you must add a trace listener to the System. ServiceModel. MessageLogging trace source and set attributes for the <messagelogging> element in the configuration file.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With