Logging block not picking up custom trace listener type in Entlib 5.0

Topics: Logging Application Block
Aug 17, 2010 at 8:00 AM
Edited Aug 17, 2010 at 8:01 AM
I'm trying to create a custom FormattedDatabaseTraceListener that replaces the standard version shipped with version 5.0. This is my logging config: <loggingConfiguration name="Logging Application Block" tracingEnabled="true" defaultCategory="General"> <listeners> <add name="Database Trace Listener" type="ComCard.Components.FormattedDatabaseTraceListener, ComCard.Components" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" databaseInstanceName="ComCard2008" writeLogStoredProcName="ComCard.Logging_WriteEntry" addCategoryStoredProcName="ComCard.Logging_AddCategory" formatter="Text Formatter" /> </listeners> <formatters> <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" template="{message} Extended Properties: {dictionary({key} - {value} )}" name="Text Formatter" /> </formatters> <categorySources> <add switchValue="All" name="General"> <listeners> <add name="Database Trace Listener" /> </listeners> </add> </categorySources> <specialSources> <allEvents switchValue="All" name="All Events" /> <notProcessed switchValue="All" name="Unprocessed Category" /> <errors switchValue="All" name="Logging Errors & Warnings"> <listeners> <add name="Database Trace Listener" /> </listeners> </errors> </specialSources> </loggingConfiguration> My trace listener isn't getting invoked at all though. After a bit of rather frustrating debugging with the shipped PDBs and source, I found that the standard FormattedDatabaseTraceListener is being wired up instead, despite my configuration. Looking at the code for FormattedDatabaseTraceListenerData I saw this: protected override Expression<Func<TraceListener>> GetCreationExpression() { return () => new FormattedDatabaseTraceListener( Container.Resolved<Data.Database>(DatabaseInstanceName), WriteLogStoredProcName, AddCategoryStoredProcName, Container.ResolvedIfNotNull<ILogFormatter>(Formatter)); } Which is hardcoded to return the standard trace listener. As an experiment, I derived my own class from this class and overrided GetCreationExpression() to return my custom type, and voila, it all started working as expected. I can only assume that GetCreationExpression() is what actually gets called now to create the listener instance. I don't know if this is a bug or not - can anyone explain why this behaviour occurs and if there is a better way to implement this scenario? It seems a bit wrong to specify a value in configuration only to have it ignored completely. Thanks!
Aug 17, 2010 at 8:17 AM

It's not a bug, it creates the out-of-the-box database trace listener because you used the FormattedDatabaseTraceListenerData as the listenerDataType:

listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

If you want to use your custom database trace listener, open your config using the entlib config tool, add a Custom Trace Listener, and locate your custom trace listener from the available assemblies.  However, this only provides basic integration.  If you want full integration with the config, you must create a class which inherits from the TraceListenerData class.  That class will expose the things you want to be able to configure in the config tool as public properties.  In essence,it will be the listenerDataType of your custom trace listener.   For the detailed steps on how to do this, please refer to this topic in the documentation.


Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.

Aug 17, 2010 at 8:43 AM
Thanks for the reply, I'll look at using a custom trace listener instead.