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.

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'.".

Post By
Josh Twist
06:27
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
00:08
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
02:49
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
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
13:26
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
06:41
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
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
13:26
Hi Himadri, I'm afraid I don't undestand your question. What do you mean by 'in a single file'?
Josh