how to log custom error messages in database

Topics: Exception Handling Application Block, Logging Application Block
Mar 10, 2009 at 12:57 PM
hi
iam using enterpise library 3.0 for logging exception into database.
now my current need is to log the exception that occurs in the presentation layer.ie..web application.

let say scenario

suppose there is user with  named : Sam
logged into the website and he is navigating the website and he doing some operation which raised any error
the error is not database related exception
so all i need is i want to log the custom exception
i need to log

userid
funcationname
webpage
like that...
into database.
so far i have been logging exception by creating policies.which will log the exception into database what ever exception is raised.now i need to add some more custom messages.how to do that
Mar 11, 2009 at 3:26 AM
You can either create your custom exception handler or custom trace listener.  If you choose to create a custom exception handler, in the HandleException method, add the extra information you need to log in the Data collection property of the exception (exception.Data.Add("userId", userId);).  If you want a custom traceListener, you can pass a dictionary object which contains those extra informations you want and pass it during the call to Logger.Write method.  In both cases, you need to edit the TextFormatter and add each token for each information. Example:
UserId : {keyvalue(userId)}.   You can also refer to this thread - http://www.codeplex.com/entlib/Thread/View.aspx?ThreadId=46045


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Mar 11, 2009 at 6:19 AM
can you give me some example how to log custome log message into database like userid....
Mar 11, 2009 at 6:53 AM
If you need it to have separate columns in your database table for those information, you would have to create your own database and custom database trace listener.  What example you specifically want for this?  If you want to know how the custom trace listener would look like, I suggest you look at the documentation on how to create custom trace listeners, open the source code of entlib and copy the implementation of the formatteddatabase tracelistener and modify it to accommodate those extra fields. 


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Mar 11, 2009 at 7:42 AM
Can i send you the example code where i got struck...
please help me out
Mar 11, 2009 at 7:47 AM
sure


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Mar 11, 2009 at 8:03 AM
i have sent a mail already..but any way here is my code

<?

 

xml version="1.0"?>

 

<!--

 

 

Note: As an alternative to hand editing this file you can use the

web admin tool to configure settings for your application. Use

the Website->Asp.Net Configuration option in Visual Studio.

A full list of settings and comments can be found in

machine.config.comments usually located in

\Windows\Microsoft.Net\Framework\v2.x\Config

-->

<

 

configuration>

 

<

 

configSections>

 

<

 

section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>

 

<

 

section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>

 

<

 

section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>

 

</

 

configSections>

 

<

 

loggingConfiguration name="Logging Application Block" tracingEnabled="true" defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">

 

<

 

listeners>

 

<

 

add databaseInstanceName="Connection String" writeLogStoredProcName="WriteLog" addCategoryStoredProcName="AddCategory" formatter="Text Formatter" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" traceOutputOptions="None" type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" name="Database Trace Listener"/>

 

</

 

listeners>

 

<

 

formatters>

 

<

 

add template="Timestamp: {timestamp}&#xA;Message: {message}&#xA;Category: {category}&#xA;Priority: {priority}&#xA;EventId: {eventid}&#xA;Severity: {severity}&#xA;Title:{title}&#xA;Machine: {machine}&#xA;Application Domain: {appDomain}&#xA;Process Id: {processId}&#xA;Process Name: {processName}&#xA;Win32 Thread Id: {win32ThreadId}&#xA;Thread Name: {threadName}&#xA;Extended Properties: {dictionary({key} - {value}&#xA;)}" type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 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 &amp; Warnings">

 

<

 

listeners>

 

<

 

add name="Database Trace Listener"/>

 

</

 

listeners>

 

</

 

errors>

 

</

 

specialSources>

 

</

 

loggingConfiguration>

 

<

 

exceptionHandling>

 

<

 

exceptionPolicies>

 

<

 

add name="Exception Policy">

 

<

 

exceptionTypes>

 

<

 

add type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" postHandlingAction="NotifyRethrow" name="Exception">

 

<

 

exceptionHandlers>

 

<

 

add logCategory="General" eventId="100" severity="Error" title="Custom Exception" formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" priority="0" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" name="Logging Handler"/>

 

</

 

exceptionHandlers>

 

</

 

add>

 

</

 

exceptionTypes>

 

</

 

add>

 

</

 

exceptionPolicies>

 

</

 

exceptionHandling>

 

<

 

connectionStrings>

 

<

 

add name="Connection String" connectionString="Data Source=ZENWORKS;Initial Catalog=Anres;Persist Security Info=True;User ID=anres;Password=anres001" providerName="System.Data.SqlClient"/>

 

</

 

connectionStrings>

 

<

 

appSettings/>

 

<

 

system.web>

 

<!--

 

 

Set compilation debug="true" to insert debugging

symbols into the compiled page. Because this

affects performance, set this value to true only

during development.

 

 

-->

 

<

 

compilation debug="true">

 

<

 

assemblies>

 

<

 

add assembly="System.Management, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>

 

<

 

add assembly="System.Configuration.Install, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>

 

<

 

add assembly="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>

 

<

 

add assembly="System.Messaging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>

 

<

 

add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>

 

<

 

add assembly="System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>

 

<

 

add assembly="System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/></assemblies></compilation>

 

<!--

The <authentication> section enables configuration

of the security authentication mode used by

ASP.NET to identify an incoming user.

 

 

-->

 

<

 

authentication mode="Windows"/>

 

<!--

The <customErrors> section enables configuration

of what to do if/when an unhandled error occurs

during the execution of a request. Specifically,

it enables developers to configure html error pages

to be displayed in place of a error stack trace.

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">

<error statusCode="403" redirect="NoAccess.htm" />

<error statusCode="404" redirect="FileNotFound.htm" />

</customErrors>

 

 

-->

 

</

 

system.web>

 

</

 

configuration>

--

 

 

protected void Page_Load(object sender, EventArgs e)

 

{

 

try

 

 

 

 

{

 

throw new Exception();

 

}

 

catch(Exception ex)

 

{

Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.

ExceptionPolicy.HandleException(ex,"Exception Policy");

 

}

}

its logging the following exception in database..

57 100 0 Error Custom Exception 3/11/2009 6:27:00 AM TAOD-13 39a5de0-1-128812264105283706 3512 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.EXE NULL 3964 HandlingInstanceID: 7b4af528-b530-4407-9248-81e0119e218f
An exception of type 'System.Exception' occurred and was caught.
----------------------------------------------------------------
03/11/2009 11:57:00
Type : System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Exception of type 'System.Exception' was thrown.
Source : App_Web_5py9plwy
Help link :
Data : System.Collections.ListDictionaryInternal
TargetSite : Void Page_Load(System.Object, System.EventArgs)
Stack Trace :    at _Default.Page_Load(Object sender, EventArgs e) in c:\Documents and Settings\surendiranb\Desktop\WebSite\Default.aspx.cs:line 18

Additional Info:

MachineName : TAOD-13
TimeStamp : 3/11/2009 6:27:00 AM
FullName : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
AppDomainName : 39a5de0-1-128812264105283706
ThreadIdentity : TARANGBLR\surendiranb
WindowsIdentity : TARANGBLR\surendiranb
Timestamp: 3/11/2009 6:27:00 AM
Message: HandlingInstanceID: 7b4af528-b530-4407-9248-81e0119e218f
An exception of type 'System.Exception' occurred and was caught.
----------------------------------------------------------------
03/11/2009 11:57:00
Type : System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Exception of type 'System.Exception' was thrown.
Source : App_Web_5py9plwy
Help link :
Data : System.Collections.ListDictionaryInternal
TargetSite : Void Page_Load(System.Object, System.EventArgs)
Stack Trace :    at _Default.Page_Load(Object sender, EventArgs e) in c:\Documents and Settings\surendiranb\Desktop\WebSite\Default.aspx.cs:line 18

Additional Info:

MachineName : TAOD-13
TimeStamp : 3/11/2009 6:27:00 AM
FullName : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
AppDomainName : 39a5de0-1-128812264105283706
ThreadIdentity : TARANGBLR\surendiranb
WindowsIdentity : TARANGBLR\surendiranb

Category: General
Priority: 0
EventId: 100
Severity: Error
Title:Custom Exception
Machine: TAOD-13
Application Domain: 39a5de0-1-128812264105283706
Process Id: 3512
Process Name: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.EXE
Win32 Thread Id: 3964
Thread Name:
Extended Properties:
i want to store to which logged in user the exception has raised...like that...
how to do that...is it possible to store it in ThreadName field..if that is the case how to do that..
please hlep me...

Mar 11, 2009 at 8:47 AM

So you want to just log the user id to an existing column and avoid creating your own database or table?  If you really intend to do this, you can set the Thread.CurrentThread.Name to the value of your user id.


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

Mar 11, 2009 at 9:29 AM
in case if i want to add another field into the same table, but using the same code ie..app.config (Same policy)
how to do that


ie...adding UserId field in the Log Table....
Mar 11, 2009 at 9:29 AM
in case if i want to add another field into the same table, but using the same code ie..app.config (Same policy)
how to do that


ie...adding UserId field in the Log Table....
Mar 11, 2009 at 9:40 AM
That is not directly supported by entlib.  First, that would automatically mean a change in the stored proc used when writing logs to db to include that extra field.  Of course you could always modify the sp
 but what about the parameters being passed in that sp?  That requires modification also of the source code.  So the solution would be to modify the source code or just extend it by creating your own
 database tracelistener.  


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Mar 11, 2009 at 9:54 AM
i need to know both the cases
case :Changing stored proc
which part of the source code i need to change to add parameter.

in case of creating custom database tracelistener
how to do that..
do you have any examples....
Mar 11, 2009 at 10:14 AM
I would recommend creating the custom database tracelistener because modifying the source code I think would require much effort.  I don't have any ready-made code right now but it should be easy, something like this:

[ConfigurationElementType(typeof(CustomTraceListenerData))]
public class DatabaseCustomTraceListener : CustomTraceListener
{
       public override void Write(object o)
       {
            //you can copy the implementation in the ExecuteWriteLogStoredProcedure here from the FormattedDatabaseTraceListener, add the extra parameters you want as a result of modification
                of the WriteLog sp
       }
}

The ExecuteWriteLogStoredProcedure method has a Database parameter in order to make the db calls specifically to execute the stored procedure.  In your case, you can just create the Database class inside
the Write method. 


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Mar 11, 2009 at 10:52 AM
hey
you know what "you are the best" when it comes for enterprise library.
its working fine with Thread.Name

Thank you so much for the follow up
have a nice day...
Jun 14, 2010 at 9:18 PM

I am using Enterprise Library 5.0. What modifications are needed in App.config file? How do I link the custom FormattedDatabaseTraceListener with the application.

Jun 15, 2010 at 2:00 PM

Hi,

For configuring your configuration to link your custom trace listener. Here are some useful references from the documentation.

  1. http://msdn.microsoft.com/en-us/library/ff664760(v=PandP.50).aspx - Configuration Overview (adding Trace Listener)
  2. http://msdn.microsoft.com/en-us/library/ff664708(v=PandP.50).aspx - Configuration Custom Trace Listeners

 Let us know if you may need additional assistance.

Gino Terrado
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

 

Jun 15, 2010 at 8:24 PM

Thanks for the quick reply.

The links you provided are very generic. I am looking for link specific to Database logging.

My logging involves changing the default schema by introducing additional columns to the Log table. There is a LogEntry class that encapulates all default columns in the Log table. Once I introduce additional columns, I can not use the LogEntry class and I need to have a custom LogEntry class that exposes the newly introduced columns as properties. Then how do I link the customized LogEntry class with LogWriter class.

Jun 16, 2010 at 1:27 AM

There's no configuration changes that needs to be made for the scenario you mentioned.  If you're directly calling Logger.Write, then you would simply create an instance of your customized LogEntry.  But if you're scenario involves handling exceptions using EHAB and you want your exception handlers to automatically create a customized logentry instead of the LogEntry class for each exception it handles, there's no direct way to do that.  You would need to create your own custom exception handler for that.  This blog will help.

 

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

Jul 15, 2010 at 10:27 PM
Edited Jul 18, 2010 at 10:57 PM

Sorry for getting back after a long time.

We decided to use default schema, rather than going for a custom schema. Looks like it is too much of work to add/modify the default columns used in database logging.

The default stored procedure WirteLog and WriteCategory, logs the default columns in the Logging database. If you want to introduce additional columns, you need to modify the default stored procedure and in that case no need to modify the configuration file.

My understanding, the new Custom LogEntry need to be linked with LogWriter class.

 

 

 

Jul 16, 2010 at 1:54 AM

Do you still have any questions on this?  I'm afraid I'm not clear whether you're still asking how to link your custom LogEntry to the LogWriter class or if you simply stated the approach you've taken.

 

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

Jul 18, 2010 at 11:01 PM

I gave up the idea of using custom database logging with Enterprise Library. It is too much of work. That is my understanding after experimenting with Enterprise Lib for custom database logging.