Customizing the DatabaseTraceListener

Topics: Building and extending application blocks, Logging Application Block
Jul 17, 2009 at 1:14 PM

I am using EntLib 4.1 and have been struggling with creating a custom DatabaseTraceListener to log data to our database. I could really use some guidance (either in the form of better documentation for creating a custom DatabaseTraceListener or direct help) as I am new to using the EntLib.

What I am trying to do it as follows:

  • Create 2 subclasses of LogEntry (LogEntryType1 & LogEntryType2). The reason for this is I need to log 2 different types of data to 2 different tables in our database (LogEntryType1 = record of who performed what; LogEntryType2 = application diagnostics & trace messages). When we need to log either type of entry, we simply create the required LogEntryType* object and pass it as the parameter to the Logger.
  • Create a custom DatabaseTraceListener based almost entirely on the provided one, except in the ‘ExecuteStoredProcedure( LogEntry )’ method, check the type of the LogEntry object passed in and call the proper Stored Procedure.
  • The desire would be to also have the ability to configure the names of the Stored Procedures and the Data Source through the EntLib Configuration editor (just like the existing DatabaseTraceListener).

I would appreciate any guidance that can be provided, even if it’s a link to a good article online about this subject as my searching has not produced the desired results. I find a lot of articles that say "Just inherit from CustomTraceListener, override these methods, and your good", but 95% of the functionality that I want is already in the current DatabaseTraceListener but it inherits from a different base class and I can't seem to get all of the pieces put together properly.

Jul 20, 2009 at 9:41 AM

Hi,

On your first Item, you just need to inherit from the LogEntry and add your required properties. For your point 2 and 3, when you add a Custom Trace Listener, one of its properties is the Attributes which has a key value collection where you can add the sproc name, database name, etc (these key value collection can later be manipulated inside your custom trace listener)...  Inside the Custom Database trace listener, just implement a logic that will check the type of the logentry and determine the stored procedure name from the Attributes that you've entered, create the database instance and execute the stored procedure.

Here is a sample method:

        private void ExecuteWriteLogStoredProcedure(LogEntry logEntry, Database db, DbTransaction transaction)
        {
            GetStoredProcedureNames();
            if (logEntry.GetType() == typeof(ActionLogEntry))
            {
                ExecuteSprocForAction(db, transaction, logEntry as ActionLogEntry);
            }
            else if (logEntry.GetType() == typeof(TraceLogEntry))
            {
                ExecuteSprocForTrace(db, transaction, logEntry as TraceLogEntry);
            }
        }
I have create a sample solution for this one. I'll send you the sample solution.
Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Aug 19, 2009 at 1:28 PM

Thank you for the reply. Now that I have the logging in place, how can I change which messages get logged dynamically at runtime? I know that setting the Filter property on the TraceListener will determine which messages get logged (by checking the LogEntry.Severity property), but how can I change this at runtime so we can 'dial up' the verbosity of the messages being logged for diagnosing issues in production?

We would like to deploy with a configuration that logs "Critical/Error" messages only, but if we notice an issue we can dynamically (through a setting inside our application) change the filter level to either of the other levels (Warning, Information, or Verbose).

Aug 20, 2009 at 6:02 AM

Hi,

Please try this sample code: Note that this modifies directly the logging section of the app.config

            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = "YourConfigFileName.config";
            Configuration entLibConfig = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
            LoggingSettings loggingSettings = (LoggingSettings)entLibConfig.GetSection(LoggingSettings.SectionName);

	   //for custom trace listener
            CustomTraceListenerData customTraceListener = loggingSettings.TraceListeners.Get("Custom Trace Listener") as CustomTraceListenerData;

            if (customTraceListener != null)
            {
	       //Set the new value for the filter
                customTraceListener.Filter = System.Diagnostics.SourceLevels.Verbose;
            }
	   //Saves the config file
            entLibConfig.Save();
Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Aug 24, 2009 at 6:45 PM
Edited Aug 24, 2009 at 7:37 PM

OK, I see how that would update the configuration file but that would cause our ASP.NET MVC application to recompile which is not desireable. I know that the recommended approach is to place the settings in a detached configuration file and the logging block will watch for changes and update accordingly. The new question becomes, how does the Enterprise Library (or at least the Logging Block) know to read from this file instead of the default configuration file (either app.config or web.config)?

UPDATE: Never mind... I think I found it: http://msdn.microsoft.com/en-us/library/cc511927.aspx

Aug 25, 2009 at 12:13 AM

Yes, by using configuration source. You can also see a code example in the Updating Configuration Settings at Run-time section in the entlib documentation.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Oct 23, 2009 at 6:58 PM

Hi Sarah,

I have a very similar issue as Kylek's first post, could you send me a copy of the sample code? Thanks in advance!

Oct 25, 2009 at 4:17 PM

Sarah,

I am looking at a similar scenario as Kylek was as well.  Is it possible for me to receive a copy of that sample code?  I've created a custom LogEntry that inherits from the EL LogEntry as you described.  But it's creating the custom database trace listener that I'm getting confused on.  Thanks for any help you could provide.

 

Michael

Oct 26, 2009 at 3:25 AM

Hi freedo5, I've already answered your new question in the other thread.  Chrisji, where should I send it?

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Oct 26, 2009 at 7:29 PM

atj885@gmail.com, thanks Sarah

Oct 27, 2009 at 11:04 AM

Sent...

Jan 19, 2010 at 4:29 PM

Sarah,

I too am having a similar problem with creating a custom database trace listener. Could you send me the sample code as well?

njones0002@hotmail.com

 

Thanks

Apr 27, 2010 at 8:20 PM

Could you send me the code as well. I am having the similar issues

Apr 27, 2010 at 11:36 PM

Send us an email in entlib.support@avanade.com so you won't have to post here your email ad.

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com