Email Trace Listener labels Errors as Warnings

Topics: Logging Application Block
Mar 6, 2012 at 8:37 PM

Can somebody help me understand if I'm doing something wrong or if there is a better way to do this.  When I add an Email Trace Listener and mark it to send Warnings and above all emails are sent with the "Warning" label attached to the subject line instead of what type of event actually occurred.  So I tried adding two Handlers one that handles Errors and above and one that handles Warnings and above ... but then I get duplicate messages(as I expected).

I would just like for the emails to come through with the appropriate "label" so it is easier to discern the severity from the subject line.

Also does anybody have any idea if there is a way to create your own "Source" so that entries in the "Event Log" show a source other than "Enterprise Library Logging"?

 

Thanks

 

dbl

Mar 7, 2012 at 5:31 AM
Edited Mar 7, 2012 at 5:34 AM

The EmailTraceListener should use the severity of the LogEntry as the subject of the email message.  If you are seeing a different behavior then can you post project to demonstrate the issue?

You can use any event source you want for your trace listener.  This is set by using the source property:

      <add name="Event Log Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        source="MySource" formatter="Text Formatter"
        log="Application" machineName="." traceOutputOptions="None" />

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

Mar 7, 2012 at 2:58 PM

I'll see if I can put a sample project together but the behavior I'm seeing is the email comes through with what ever "Severity" the Handler has set.  So if I have a Logging Exception Handler and the Severity is set to "Warning" then it doesn't matter what type of exception occurs the Email Trace Listener subject line come through with Prefix + "Warning" + Suffix.

Mar 7, 2012 at 3:52 PM

Below is the Web.config from a standard WCFService project called EMailTestService using the GetData call.  I removed the GetDataUsingContract call and CompositeType from the code. You will need to set the smtp server and the to address for it to work.  But in my mind the email received should have "EMailTestService Error " instead it comes in with "EMailTestService Warning".

<?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" />
    <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  </configSections>
  <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.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        source="Enterprise Library Logging" formatter="Text Formatter"
        log="" machineName="." traceOutputOptions="None" />
      <add name="Email Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.EmailTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.EmailTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        toAddress="to@example.com" fromAddress="from@example.com" subjectLineStarter="EMailTestService "
        smtpServer="testsmtp.domain.com" formatter="Text Formatter" />
    </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="General">
        <listeners>
          <add name="Event Log Listener" />
          <add name="Email 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="Event Log Listener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>
  <exceptionHandling>
    <exceptionPolicies>
      <add name="Policy">
        <exceptionTypes>
          <add name="All Exceptions" type="System.Exception, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
            postHandlingAction="NotifyRethrow">
            <exceptionHandlers>
              <add name="Logging Exception Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=5.0.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                logCategory="General" eventId="100" severity="Warning" title="Enterprise Library Exception Handling"
                formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"
                priority="0" />
            </exceptionHandlers>
          </add>
        </exceptionTypes>
      </add>
    </exceptionPolicies>
  </exceptionHandling>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <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>
  
</configuration>


And here is the GetData Call:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

namespace EmailTestService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class Service1 : IService1
    {
        ExceptionManager _exManager;

        public string GetData(int value)
        {
            _exManager = EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>();
            int result = 0;
            int zero = 0;

            result = _exManager.Process(() => value / zero, "Policy");

            return string.Format("You entered: {0}", value);
        }
    }
}


Mar 7, 2012 at 4:06 PM

OK, I see.  I didn't pick up on the fact that you are using Exception Handling.  

The EmailTraceListener sets the subject of the email to the Severity of the LogEntry:

string sendToSmtpSubject = header + logEntry.Severity.ToString() + footer;
...
message.Subject = sendToSmtpSubject;

This works fine if you are just creating a LogEntry and logging it.

One of the limitations of the exception handling logging approach is that the data to be logged is static so that you can't have dynamic information.  I've run into this where I wanted each handling location to have a unique EventId.

I think the only out of the box solution is creating separate policies (which will result in duplicate configuration). E.g. "Policy_LogWarning", "Policy_LogError".  

Other than policy name how were you thinking to identify a handling scenario as Warning or Error? 

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

Mar 7, 2012 at 4:37 PM

Not sure I see how that would help.  I don't have any idea which Policy to supply to the Exception Handler to cover the exception that is going to occur.  So having multiple policies doesn't help me.  And if I create multiple Handlers one for Errors and one for Warnings then I get duplicate messages.

Now here is the one thing that has occurred to me:  how do exceptions of type "Warning" and "Critical" occur?  They really don't do they?  So from an exception standpoint do I really need to worry about anything coming out of there except "Error"?  So setting the Severity to Error would be correct.  As I'm working though this I could see that you might want to treat specific "errors" as "warnings" and the way things are setup here I could do that.

Am I making sense?

Mar 7, 2012 at 5:20 PM

> Not sure I see how that would help.  I don't have any idea which Policy to supply to the Exception Handler to cover the exception that is going to occur.

Yes, that was my point: how can you identify the different scenarios ahead of time.  If it was dependent on the type of exception then that is very easy to handle since that fits with the design of the block.

The key point is that you are in charge of the severity of the exception logged.  In general, there is nothing intrinsic to the exception itself that determines the severity (ignoring any exceptions that might have a built-in severity like SQL Server).  Like most things, it depends on the context.

I would treat all exceptions as "Error" for logging purposes.  I would avoid using "Critical" since that should be used for an application crash and if you ever change to use the EventLogTraceListener it will log your "Critical" messages as "Error" anyway.

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