Using EL with WCF integration

Topics: Enterprise Library Core, Logging Application Block
Sep 12, 2013 at 11:15 PM
I have followed the recommended configuration for using EntLibLoggingProxyTraceListener to forward to EL Logging and the XmlTraceListener.

So far so good and at some point we will make custom database logging listener so that all logging and exception handling goes there.

But what I don't understand is how to now trace events from the server code, or xmlLogEntry(s), or exceptions that are custom so they are picked up through the same mechanism. I cannot find an explanation of how they really work together once this is configured this way.

If I define a custom event source, either area (diag or logging section) it doesn't get logged anywhere and I am unsure if I have the wrong format or configuration or code. I have tried various settings with using a flat file for the unprocessed, and errors etc...which did log parts of the xml from the other errors, but I don't see anything logged for the custom source name="myTrace"..

If someone could post a sample config with a custom defined source, and point me towards the code that would log it, that would be appreciated.

Thanks in advance.
Mac
Editor
Sep 13, 2013 at 1:47 AM
So far so good and at some point we will make custom database logging listener so that all logging and exception handling goes there.

Just a note that if you are using the out of the box Logging schema for WCF messages then the Title column should be changed to allow NULL. See http://entlib.codeplex.com/discussions/361057.
But what I don't understand is how to now trace events from the server code, or xmlLogEntry(s), or exceptions that are custom so they are picked up through the same mechanism. I cannot find an explanation of how they really work together once this is configured this way.

As you say the EntLibLoggingProxyTraceListener hooks into the System.Diagnostics trace listener infrastructure and then invokes the Logging Application Block.
If I define a custom event source, either area (diag or logging section) it doesn't get logged anywhere and I am unsure if I have the wrong format or configuration or code.

Try configuring the errors special source...perhaps there is an error occurring. Feel free to post your specific code/configuration and then we can see what's going on.

Here's the example I'm using where I trace all WCF messages as well as writing my own message to the trace.svclog file.

Here is my configuration (based on that previous thread):
<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
    </configSections>

  <loggingConfiguration name="Logging Application Block" tracingEnabled="true"
    defaultCategory="System.ServiceModel" logWarningsWhenNoCategoriesMatch="true">
    <listeners>
      <add name="XML Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.XmlTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.XmlTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        fileName="trace.svclog" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, Callstack" />
    </listeners>
    <formatters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        template="Timestamp: {timestamp}{newline}&#xA;Message: {message}{newline}&#xA;Category: {category}{newline}&#xA;Priority: {priority}{newline}&#xA;EventId: {eventid}{newline}&#xA;Severity: {severity}{newline}&#xA;Title:{title}{newline}&#xA;Machine: {localMachine}{newline}&#xA;App Domain: {localAppDomain}{newline}&#xA;ProcessId: {localProcessId}{newline}&#xA;Process Name: {localProcessName}{newline}&#xA;Thread Name: {threadName}{newline}&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
        name="Text Formatter" />
    </formatters>
    <categorySources>
      <add switchValue="All" name="System.ServiceModel">
        <listeners>
          <add name="XML Trace Listener" />
        </listeners>
      </add>
      <add switchValue="All" name="General">
        <listeners>
          <add name="XML Trace Listener" />
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="All" name="All Events" />
      <notProcessed switchValue="All" name="Unprocessed Category" />
      <errors switchValue="All" name="Logging Errors &amp; Warnings">
        <listeners>
          <add name="XML Trace Listener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <diagnostics>
      <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtTransportLevel="true"
logMessagesAtServiceLevel="true"/>
    </diagnostics>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

    <system.diagnostics>
      <sources>
        <source name="System.ServiceModel" switchValue="All" propagateActivity="true">
          <listeners>
            <add name="traceListener"
            type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.EntLibLoggingProxyTraceListener,Microsoft.Practices.EnterpriseLibrary.Logging"/>
          </listeners>
        </source>
      </sources>
    </system.diagnostics>

</configuration>

So the categories "System.ServiceModel" and "General" both get written to the XML Trace Listener. (Note that in this example I also set the errors specialSource to use the XML Trace Listener even though that I don't recommended that.)

Then the service looks like:
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            try
            {
                Logger.Write("Entering GetData", "General");

                if (value == 1) throw new ArgumentException("value cannot be 1", "value");

                return string.Format("You entered: {0}", value);
            }
            catch (Exception ex)
            {
                MyFault mf = new MyFault() { MyInfo = ex.Message };
                throw new FaultException<MyFault>(mf, new FaultReason(mf.MyInfo));
            }
        }
    }

When I invoke the service I get 131 entries in the trace.svclog file: 130 WCF tracing entries and 1 entry saying "Entering GetData".

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to