none
Is it possible to programmatically configure WCF logging? RRS feed

  • Question

  • Hello,

    Our WCF services are configured using custom configuration files where we use our own configuration structure. We would like to add WCF log configuration to it, to be able to forward WCF log messages to Enterprise Library logging application block. I haven't found if this can be done programmatically, but the following statement from an older post looks discouraging:

    “AS for the WCF trace source and listeners, I've checked its internal implementation via reflector, it seems the TraceSource are not normal TraceSource, but some internally implemented source types(which is not open to public, marked as internal). Therefore, I'm afraid we cannot programmtically initialize these trace source and listeners in our code. “ (http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/634c4835-87df-4ce3-aae5-db9da65bc824)


    Is this really so that the only way to configure WCF logging is via system.serviceModel section of App.config?


    Vagif Abilov
    Monday, September 14, 2009 1:01 PM

Answers

  • you can do something like the code below to programatically configure logging. 
    This is one of the ways, not the only way to do this progamatically.

    string traceFileName = ""; //set your trace file name here..
    
                ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
                configFileMap.ExeConfigFilename = @"MyCfg.config";
                Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
    
                ServiceModelSectionGroup serviceModelSectionGroup = (ServiceModelSectionGroup)config.GetSectionGroup("system.serviceModel");
                serviceModelSectionGroup.Diagnostic.MessageLogging.MaxMessagesToLog = 1000;
                serviceModelSectionGroup.Diagnostic.MessageLogging.LogEntireMessage = true;
                serviceModelSectionGroup.Diagnostic.MessageLogging.LogMessagesAtServiceLevel = true;
                serviceModelSectionGroup.Diagnostic.MessageLogging.LogMessagesAtTransportLevel = true;
    
                string rawXml =
    @"  <system.diagnostics>
        <sources>
          <source name=""System.ServiceModel"" switchValue=""Verbose, ActivityTracing"" propagateActivity=""true"" >
            <listeners>
              <add name=""xml"" />
            </listeners>
          </source>
          <source name=""System.ServiceModel.MessageLogging"" switchValue=""Verbose"">
            <listeners>
              <add name=""xml"" />
            </listeners>
          </source>
        </sources>
        <sharedListeners>
          <add name=""xml"" type=""System.Diagnostics.XmlWriterTraceListener"" initializeData=""" + traceFileName + @""" />
        </sharedListeners>
        <trace autoflush=""true"" />
      </system.diagnostics>";
    
                config.Save();
    
                string temp = File.ReadAllText(config.FilePath);
                temp = temp.Replace("</configuration>", rawXml + Environment.NewLine + "</configuration>");
    
                File.WriteAllText(config.FilePath, temp);

    Amit Sharma
    Monday, September 14, 2009 3:46 PM
    Moderator

All replies

  • if you only need to log WCF messages, you can implement shared listener and call the logging class from there.

    <
    system.diagnostics>
       <trace>
          <
    listeners>
             <
    add name="ServMsg" />
          </
    listeners>
       </
    trace>
       <
    sources>
          <
    source name="System.ServiceModel.MessageLogging">
             <
    listeners>
                <
    add name="ServMsg" />
             </
    listeners>
          </
    source>
       </
    sources>
       <
    sharedListeners>
          <
    add name="ServMsg" type="Class, Namespace, Version=1.0.0.0,Culture=neutral, PublicKeyToken=83a5bd8f13688901" />
       </
    sharedListeners>
    </
    system.diagnostics>

    <

     

    system.serviceModel>
    <
    diagnostics>
    <
    messageLogging logEntireMessage="false" maxMessagesToLog="300" logMessagesAtServiceLevel="false" logMalformedMessages="false" logMessagesAtTransportLevel="false" />
    </
    diagnostics>
    </system.serviceModel>

    Set true whatever you need.  the class would inherit from System.Diagnostics.TraceListener and implementation of Write can log.

    Happy Coding!


    kashif
    Monday, September 14, 2009 3:39 PM
  • you can do something like the code below to programatically configure logging. 
    This is one of the ways, not the only way to do this progamatically.

    string traceFileName = ""; //set your trace file name here..
    
                ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
                configFileMap.ExeConfigFilename = @"MyCfg.config";
                Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
    
                ServiceModelSectionGroup serviceModelSectionGroup = (ServiceModelSectionGroup)config.GetSectionGroup("system.serviceModel");
                serviceModelSectionGroup.Diagnostic.MessageLogging.MaxMessagesToLog = 1000;
                serviceModelSectionGroup.Diagnostic.MessageLogging.LogEntireMessage = true;
                serviceModelSectionGroup.Diagnostic.MessageLogging.LogMessagesAtServiceLevel = true;
                serviceModelSectionGroup.Diagnostic.MessageLogging.LogMessagesAtTransportLevel = true;
    
                string rawXml =
    @"  <system.diagnostics>
        <sources>
          <source name=""System.ServiceModel"" switchValue=""Verbose, ActivityTracing"" propagateActivity=""true"" >
            <listeners>
              <add name=""xml"" />
            </listeners>
          </source>
          <source name=""System.ServiceModel.MessageLogging"" switchValue=""Verbose"">
            <listeners>
              <add name=""xml"" />
            </listeners>
          </source>
        </sources>
        <sharedListeners>
          <add name=""xml"" type=""System.Diagnostics.XmlWriterTraceListener"" initializeData=""" + traceFileName + @""" />
        </sharedListeners>
        <trace autoflush=""true"" />
      </system.diagnostics>";
    
                config.Save();
    
                string temp = File.ReadAllText(config.FilePath);
                temp = temp.Replace("</configuration>", rawXml + Environment.NewLine + "</configuration>");
    
                File.WriteAllText(config.FilePath, temp);

    Amit Sharma
    Monday, September 14, 2009 3:46 PM
    Moderator
  • if you only need to log WCF messages, you can implement shared listener and call the logging class from there.

    <
    system.diagnostics >
       < trace >
          <
    listeners >
             <
    add name = " ServMsg " />
          </
    listeners >
       </
    trace >
       <
    sources >
          <
    source name = " System.ServiceModel.MessageLogging " >
             <
    listeners >
                <
    add name = " ServMsg " />
             </
    listeners >
          </
    source >
       </
    sources >
       <
    sharedListeners >
          <
    add name = " ServMsg " type = " Class, Namespace, Version=1.0.0.0,Culture=neutral, PublicKeyToken=83a5bd8f13688901 " />
       </
    sharedListeners >
    </
    system.diagnostics >

    <

     

    system.serviceModel >
    <
    diagnostics >
    <
    messageLogging logEntireMessage = " false " maxMessagesToLog = " 300 " logMessagesAtServiceLevel = " false " logMalformedMessages = " false " logMessagesAtTransportLevel = " false " />
    </
    diagnostics >
    </system.serviceModel >

    Set true whatever you need.  the class would inherit from System.Diagnostics.TraceListener and implementation of Write can log.

    Happy Coding!


    kashif

    Thanks Kashif, but my question was about how to avoid doing all this via configuration.
    Vagif Abilov
    Monday, September 14, 2009 3:56 PM
  • Thank you Amit, of course I'd prefer a solution where it was possible to set logging settings directly, but now that is seems to be impossible your approach might be the easiest workaround.

    Vagif

    Vagif Abilov
    Monday, September 14, 2009 3:58 PM
  • yes you can. just write in your code: Trace.Listeners.Add(new TraceListener());
    Thursday, February 28, 2013 4:23 PM