How to Enable/Disable WCF Tracing through code
Recently I was working on logging WCF messages in our project. However, I found out that we cant really enable/disable logging programatically or through code in the same appdomain as wcf service.We can see why here.
This
forum actually tells the solution of creating a different appdomain to
log the traces or creating a config file dynamically and saving it as
app.config.
My requirement was just to enable/disable the logging dynamically. So, I had no problems in having a config file as such but wanted to turn the flag enabletracing=false through the code.
My another requirement was that the log file generated should be readable by svctraceviewer. I also tried some examples where it is shown that if we override XMLWriterTraceListners methods Write and WriteLine.However, the trace file generated wasnt logging complete messages.
Below steps ensure how I achieved the above requirements. I feel this could be a common requirement in production environments where we need to switch on the tracing depending upon our common LoggingEnabled=True/False. This flag would indicate a general logging policy in the application and need not be specific to WCF tracing.
The solution is to create a custom listner which in its constructor actually decides whether to log in a file or not. Following are the steps to achieve the solution.
1.Create our normal WCF sources for logging in config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Warning,ActivityTracing">
<listeners>
<add name="CustomListner"/>
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging" switchValue="Warning,
ActivityTracing">
<listeners>
<add name="CustomListner" />
</listeners>
</source>
</sources>
<sharedListeners>
<add type="WCFTracing.CustomTraceListner,
WCFTracing, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
name="CustomListner" />
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logKnownPii="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" />
<endToEndTracing activityTracing="true" />
</diagnostics>
</system.serviceModel>
</configuration>
2. Create a custom listner class which is mentioned in the config. Please note the function "CheckIfAllowed". This actually returns a memory stream in case logging is turned off. This ensures that the constructor doesn't fail and also no file is generated. Also, we are limiting buffer of memory stream to 2 bytes.And that's it. You can view the file using svctraceviewer conveniently.
public class CustomTraceListner : XmlWriterTraceListener
{
public CustomTraceListner()
:
base(CheckIfAllowed())
{
}
private static Stream CheckIfAllowed()
{
bool ifAllowed = true;
if (ifAllowed)
return new
FileStream(@"D:\temp.svclog",
FileMode.OpenOrCreate, FileAccess.Write);
return new MemoryStream(2);
}
}