Using Exception Shielding and Logging together

Topics: Exception Handling Application Block, Logging Application Block
Nov 22, 2011 at 6:36 PM
Edited Nov 23, 2011 at 3:08 PM

I'm having some trouble getting both the Exception Shielding and Logging working together within the same WCF application.  The shielding part I've gotten working fine however, i'm having trouble getting the Logging to work with it.

Here are my requirements:

  1. Convert ValidationException (this is a custom Exception class and not from Validation Block) to FaultContract
  2. Convert all other exceptions to FaultContract
  3. Log all exceptions to Event Log
    • I'm only interested in logging the Exception information and not anything WCF specific
    • Must be Event Log, Xml file or anything else is irrelevant

I had essentially put two policies one for Shielding and one for Logging, however the logging one isn't working as expected. 

Here is how the Exception Handling Hierarchy looked:

  • Shielding Policy
    • System.Exception (ThrowNewException)
      • FaultContractExceptionHandler
    • ValidationException (ThrowNewException)
      • FaultContractExceptionHandler
  • Logging Policy
    • System.Exception (NotifyRethrow)
      • LoggingExceptionHandler

My Logging Configuration is:

<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
    <listeners>
      <add name="Event Log Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        source="Proof of Concept Application" formatter="Text Formatter"
        log="" machineName="." traceOutputOptions="None" />
    </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="General">
        <listeners>
          <add name="Event Log 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="Event Log Listener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>

How would I go about implementing this?

Nov 23, 2011 at 12:10 AM
Edited Nov 23, 2011 at 12:10 AM

"however the logging one isn't working as expected"

 What specifically is the problem?  If the problem is the messages are not being logged it could be because you don't have permission to create the Event Source  "Proof of Concept Application".

"I'm only interested in logging the Exception information and not anything WCF specific"

What does not anything WCF specific mean?  Do you mean like trace information?


What if you had one policy that handled ValidationException and System.Exception.  And each exception had 2 handlers: a logging handler and  FaultContractHandler?

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

Nov 23, 2011 at 1:39 PM

That is correct the messages aren't being logged.  I'm pretty sure I can create the Event Source as i'm in the Administrators group on that machine, i'll double check that though.

When I say WCF Specific, I mean the tracing information that is generated when you use .svclog log files.

I hadn't tried to use a single policy. I thought I had read somewhere (can't find where now) that the PostHandlingAction needed to be NotifyRethrow and since the shielding policy needed ThrowNewException hence the two policies.  Now i'm probably going to need to add the Logging Handler to both Exception types, correct?

Nov 23, 2011 at 3:34 PM

Ok got it working by adding the Exception Handlers to the Shielding Policy.

Just for my clarification, if I define an exception policy in the config it will not run automatically if there is an unhandled exception will it?

Nov 23, 2011 at 10:50 PM

Good to hear.  

No, the policies do not run automatically when there is an unhandled exception.  The only policy (or policies) that are executed are the ones
that have been configured to run via the[ExceptionShielding("Policy")] attribute.

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

Jan 20, 2012 at 2:20 PM

this is my configuration. but I still can't see anything logged into eventvwr. can somebody please help?

I've the permission to create eventsource.

 <loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">    <listeners>      <add name="Event Log Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"        source="Enterprise Library Logging" formatter="Text Formatter"        log="Application" machineName="." traceOutputOptions="None" />    </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="General">        <listeners>          <add name="Event Log 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="Event Log Listener" />        </listeners>      </errors>    </specialSources>  </loggingConfiguration>  <exceptionHandling>    <exceptionPolicies>      <add name="WCF Exception Shielding">        <exceptionTypes>          <add name="All Exceptions" type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"            postHandlingAction="ThrowNewException">            <exceptionHandlers>              <add type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.FaultContractExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF"                faultContractType="Contracts.ServiceFault, Contracts" name="DefaultFaultContract Handler">                <mappings>                  <add source="{Guid}" name="Id" />                  <add source="{Message}" name="MessageText" />                </mappings>              </add>              <add name="Logging Exception Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"                logCategory="General" eventId="100" severity="Error" title="Enterprise Library Exception Handling"                formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"                priority="0" />            </exceptionHandlers>          </add>        </exceptionTypes>      </add>    </exceptionPolicies>  </exceptionHandling>

Jan 23, 2012 at 5:57 AM

I recommend posting a new discussion to address your specific issue.

Thanks.

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

Jan 23, 2012 at 8:08 AM

I understand. 

I had rights issue and the new event source issue.

I got these fixed and rest was smooth.

So another thread won't be necessary?

Kavya