Logging WCF FaultException to Database

Topics: Data Access Application Block, Logging Application Block
Jun 27, 2012 at 1:39 AM

Hi there,

Visual Studio 2010, SQL Server 2008, Ent Lib 5.0

Configured Enterprise Library: Logging and Data application blocks and the exception is logged into Log table.

BUT the actual exception thrown using FaultException in Service is ignored (Not logging). The objective is to log service exceptions for trouble shooting.

Help is appreciated in logging the Service exception i.e., FaultExceptions stack trace. Configuration is accessible at http://entlib.codeplex.com/discussions/359855 Apologies for cross thread posting.

Best

sukumarraju

 

Jun 29, 2012 at 6:01 AM

It sounds to me like you may want to use Exception Shielding combined with logging to log exception information to the database.  There is an example on the Sample Projects page.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Jun 29, 2012 at 10:28 AM
Edited Jun 29, 2012 at 10:30 AM
randylevy wrote:

It sounds to me like you may want to use Exception Shielding combined with logging to log exception information to the database. 

Thanks Randy,

Please note that below is the source from Catch block.

 

catch (Exception ex)
            {
                ServiceException oe = new ServiceException();
                oe.Content = ex.Message;

                throw new FaultException<ServiceException>(oe, new FaultReason(oe.Content));
            }

 

Note that without amending existing implementation it is required to log exceptions through Web.config, which is explained at

http://msdn.microsoft.com/en-us/library/ms733025.aspx

As explained in the inital posting I am implementing above MSDN suggested solution (Web.config) where the service trace is logged BUT the excetption stack trace is ignored.

Also note that only Logging and database application blocks are used. Not intending to use Exception handling block as it demands amendment in source code.

Further help is appreciated.

Jun 29, 2012 at 2:15 PM
Edited Jun 29, 2012 at 2:20 PM

Do you have the errors special source configured?  I always recommend having the errors special source set to a trace source that is unlikely to fail (e.g. flat file).  Not just for troubleshooting development but for when things go wrong in production (e.g. when a database write fails you can recover the lost message from the errors special source as well as investigate the issue).  

When I configure the errors special source I see many error messages: 

Message: Cannot insert the value NULL into column 'Title', table 'LoggingDefault.dbo.Log'; column does not allow nulls. INSERT fails.

It looks like the title property is frequently not set when using WCF diagnostics with the proxy trace listener (and other times it is actually set to an empty string) so many messages fail (e.g. Start, Suspend, Error).

If I modify the Title column on the Log table to allow nulls then everything looks like it is working fine.    If you make that small change then it should work properly.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Jun 29, 2012 at 4:14 PM
randylevy wrote:

Do you have the errors special source configured?  I always recommend having the errors special source set to a trace source that is unlikely to fail (e.g. flat file).  Not just for troubleshooting development but for when things go wrong in production (e.g. when a database write fails you can recover the lost message from the errors special source as well as investigate the issue).  

When I configure the errors special source I see many error messages: 

Message: Cannot insert the value NULL into column 'Title', table 'LoggingDefault.dbo.Log'; column does not allow nulls. INSERT fails.

It looks like the title property is frequently not set when using WCF diagnostics with the proxy trace listener (and other times it is actually set to an empty string) so many messages fail (e.g. Start, Suspend, Error).

If I modify the Title column on the Log table to allow nulls then everything looks like it is working fine.    If you make that small change then it should work properly.

Thanks Randylevy.

I have implemented your suggesitons i.e., 1. Special sources already configured 2. Title column in Log table set is allow nulls now.

Still the exception is NOT logged into database except other service trace. Where as the xml trace listener log seems to be logging the exception stack.

Please refer below configuration. Help is greatly appreciated.

<configuration>
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />

    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
      
  </configSections>

  <loggingConfiguration name="Logging Application Block" tracingEnabled="true" defaultCategory="System.ServiceModel"
    logWarningsWhenNoCategoriesMatch="true">
    <listeners>

      <add name="Database Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
      listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        databaseInstanceName="LINT" writeLogStoredProcName="WriteLog"
        addCategoryStoredProcName="AddCategory" formatter="Text Formatter"
        traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack"
        filter="All" />

      <add name="XML Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.XmlTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.XmlTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        fileName="e:\\trace-xml.log" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, Callstack" />

</listeners>

<formatters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.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="Database Trace Listener" />
            <add name="XML Trace Listener" />

        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="All" name="All Events" />
      <notProcessed switchValue="All" name="Unprocessed Category">
        <listeners>
          <add name="Database Trace Listener" />
            <add name="XML Trace Listener" />

        </listeners>
      </notProcessed>
      <errors switchValue="All" name="Logging Errors &amp; Warnings">
        <listeners>
          <add name="Database Trace Listener" />
            <add name="XML Trace Listener" />

        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>

<dataConfiguration defaultDatabase="INT" />

 <system.serviceModel>
      
      <!-- Diagnostics section-->  
      <diagnostics>
          <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtTransportLevel="true"
logMessagesAtServiceLevel="true"/>

</system.serviceModel>

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

Jun 29, 2012 at 4:46 PM
Edited Jun 29, 2012 at 5:02 PM

You should set the special sources to its own dedicated trace listener (don't use the "regular" trace listeners since, if the errors special source trace listener is being executed, one of the "regular" trace listener has already failed (and likely could fail again)!).

Using your configuration it seems to be working for me.  Are you seeing an Error severity record but with no stack trace or no Error severity record?

Perhaps if you can post a sample project to recreate the issue?

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Jul 2, 2012 at 12:00 PM
randylevy wrote:

You should set the special sources to its own dedicated trace listener (don't use the "regular" trace listeners since, if the errors special source trace listener is being executed, one of the "regular" trace listener has already failed (and likely could fail again)!).

Using your configuration it seems to be working for me.  Are you seeing an Error severity record but with no stack trace or no Error severity record?

Perhaps if you can post a sample project to recreate the issue?

Thanks very much Randy.

Yes, you are right. Exception stack trace is written to Logging database (Log table). I was my mistake for NOT checking the databse properly.

As current SwitchValue set to 'All'  each service call generating 67 rows of data in Log table with the above configuration. Same number of rows created when an exception is occurred as well.

 Please inform what areas of configuraiton be set to 'Error' so that only when ane exception occurs then only data is logged.

Your help so far is greatly appreciated.

Best

Jul 3, 2012 at 4:05 AM

You can set the "Minimum Severity" (in the config tool) on the category ("System.ServiceModel") to "Error" or you can set the "Severity Filter" (in the config tool) on the individual Trace Listener ("Database Trace Listener") to "Error".  You would do the latter when you want one trace listener in the category to have a different severity value than another.  So you could have an XML Trace Listener log all Information messages but have Database Trace Listener (or Email Trace Listener, for example) log only Errors.

In the configuration file the Minimum Severity appears as "switchValue":

    <categorySources>
      <add switchValue="Error" name="System.ServiceModel">
        <listeners>
          <add name="Database Trace Listener" />
          <add name="XML Trace Listener" />
        </listeners>
      </add>
    </categorySources>

and the "Severity Filter" on a trace listener appears as simply "filter":

 

<add name="Database Trace Listener" 
... filter="Error" />

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com