Skip Navigation LinksHome > View Post

Log Event to Listener Routing in Enterprise Library

I've been working with Enterprise Library's logging functionality with one of my clients for the last few months and we still hadn't fully understood the Log Event to Listener routing mechanism.

Fortunately, I managed to secure some of Tom Hollander's time during my recent trip to the Patterns & Practices team in Redmond. Ultimately, it's the goal of any logging framework to take published events and route them to the appropriate listener (database, file or console window, for example) in as configurable a way as possible.

Enterprise Library Routing sequence

Logging starts with a LogEntry, which is an event that you publish to the Logging engine via the Logger.Write method. Each LogEntry has a number of properties including an integer Priority, an enumerated Severity (based on TraceEventType enumeration) and zero or more strings that represent the Categories that the entry belongs to. When you publish a LogEntry the Enterprise Library Logging engine will evaluate the event against any configured Filters. There are three Filters provided out of the box including a LogEnabledFilter which is a very effective way of short-circuiting the processing of all events, if you want logging turned off entirely. There's also a CategoryFilter and PriorityFilter provided, but it's easy enough to write your own.

<logFilters>
    <add name="LogEnabled Filter"
        type="Microsoft.Practices.EnterpriseLibrary. Logging.Filters.LogEnabledFilter, Microsoft.Practices.EnterpriseLibrary.Logging"
        enabled="true" />
</logFilters>

If your event makes it through the filters it's up to the configured Sources and the Categories to which your event belongs that decides what happens next.

In Enterprise Library you can configure a number of Category Sources (based on System.Diagnostics TraceSource but not the same) that specify a category. The Source can also contain any number of TraceListeners (see below), so in the example below, if your event belongs to the "myCategory" category it will be written to the "Database Trace Listener" and "Rolling File Listener". Note that the listeners are just referenced by name so they can be listed in multiple category sources.

<categorySources>
    <add switchValue="Information" name="myCategory">
        <listeners>
            <add name="Database Trace Listener" />
            <add name="Rolling File Listener" />
        </listeners>
    </add>
</categorySources>

Note that the Source also specified a switchValue which maps to the Severity of the LogEntry. In this case the switchValue is set to Information meaning that the source will only process LogEntries of severity 'Information' or higher.

This does mean that a common scenario supported by most logging frameworks isn't supported by EntLib. Namely, the ability to route based on Severity. Suppose you want All events to be written to your Rolling File Listener but only events with a severity of Error or higher to be written to the SMTP listener (and mailed to you). Since Ent Lib Logging only supports routing through categories, you'll need to find a workaround. An obvious one that springs to mind is to add the severity of the Entry to its categories collection. Or, you could make use of the allEvents source which is described below.

If you've ever worked with Ent Lib's configuration block you've probably noticed some odd looking configuration called specialSources. These are like the category sources above but are hardwired to pick up specific events.
  • allEvents - this source picks up all events that weren't filtered.
  • notProcessed - any event not picked up by the other sources because there was no matching category will be redirected to this source (if any listeners are specified). Note that notProcessed events do not include filtered events (LogFilters) or events that matched a category but weren't processed due to the switchValue/severity.
  • errors - this source picks up internal logging errors. It is therefore recommended not to use listeners with likely points of failure (such as a Database Trace Listener for example). Note that this is also where logWarningsWhenNoCategories match (explained shortly) does its business.
<specialSources>
    <allEvents switchValue="All" name="All Events" />
    <notProcessed switchValue="All" name="Unprocessed Category">
        <listeners>
            <add name="Rolling File Listener" />
        </listeners>
    </notProcessed>
    <errors switchValue="All" name="Logging Errors & Warnings"/>
</specialSources>

What happens if my event belongs only to categories that aren't listed? There is a boolean logWarningsWhenNoCategoriesMatch attribute on the root loggingConfiguration node, if no categories match a warning is logged to the errors specialSource with the title "There is no explicit mapping for the categories 'myCategory'.".

Tags: .NET

 
Josh Post By Josh Twist
6:27 AM
07 May 2007

» Next Post: The Difference between GAT and GAX
« Previous Post: Visiting the Patterns and Practices Team

Comments are closed for this post.

Posted by Johnson @ 11 Oct 2007 12:08 AM
Hi Josh,
can u plz tell me the entire procedure of how to send log information to a sql db using enterprise library 2.0.(how to create my own db ,table and the config file required)
if u can help me out it will be a great help.my mail id: 2ujohn@gmail.com
regards,
Jon

Posted by rudi @ 03 Apr 2009 2:49 AM
Hi Josh,
my (old) code contains a lot of system.diagnostics.trace.write(..) lines. in the new code parts i'm using the EntLib (with Logger.Write(..)). Is there an easy way to route the system.diagnostics.trace.write() output to the EntLib listeners? i don't want to change all the lines in the old code files.
thanks
regards
rudi

Posted by Drupac @ 25 Jun 2009 11:05 AM
FYI - As of version 4.0 of the Enterprise Library (May 2008), the "listeners/add" element supports a "filter" attribute to allow filtering by the message level. See http://msdn.microsoft.com/en-us/library/cc511579.aspx.

Posted by Noella @ 30 Jul 2010 1:26 PM
Just started using the Entlib and was wondering how to filter out messages based on severity . The documentation emphasizes more on Priority and Category filtering.So this post helped quite a bit.Thanks!

Posted by Rashmi @ 10 Aug 2010 6:41 AM
This is something I have been looking for. It's explained so well and in such a short tutorial. Just amazing.

Posted by Himadri @ 16 Sep 2010 12:06 PM
Hi Josh,
This is very usefull information.I have a query. Can we have multiple logFilters in single file. If yes then how can we use them. Can you send sample code for that?

Posted by Josh @ 17 Sep 2010 1:26 PM
Hi Himadri, I'm afraid I don't undestand your question. What do you mean by 'in a single file'?

Josh

© 2005 - 2014 Josh Twist - All Rights Reserved.