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);

        }

    }