Enterprise Library 4.1 Exception Handling

Topics: Exception Handling Application Block
Nov 24, 2010 at 8:41 AM

I'm new to Enterprise Library.
I need to create two type of exception handling method. one is write to event log. another one is write to SQL DB.
I have created the policy (Name - ExceptionPolicy) in enterprise library configuration. under the policy i have created one exception type then Logging Handler.
Also i checked in the EntLibConfig.exe.config file <exceptionHandling> <exceptionPolicies>. it's there.
 Now i have 2 questions to ask
1) I'm getting error (object reference not set to an instance of object) When i'm trying to handle the exception in my application
   My code :- ExceptionPolicy.HandleException(ex, "ExceptionPolicy")
2) The configuration i did for event log. now how can i do it for to write the exception to SQL DB. how should i configure for this.

 

 

 

Nov 24, 2010 at 11:33 AM

1.  You probably configured the exceptionHandling settings in a configuration file of a class library.  It should be in the config file of the host/executable project regardless of where the exception handling code is.  Class libraries don't own config files.

2.  I have mentioned the steps on configuring the database trace listener in this thread.

 

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

Nov 25, 2010 at 1:49 AM

Thanks for the reply.

I need to pass a database connectionstring dynamically from my class library instead of configuring in the enterprise library.
Please send me the sample for this.
Also, My scanario is first i need to write the error to DB. If there is any issue in stroing error details to the DB then I need to write this exception and original exception to the event log.
Can you please guide me how to do this.

Thanks in advance

Nov 25, 2010 at 2:13 AM

Do your connection strings actually change during runtime or all the possible ones can be configured in the connectionStrings section and you can just decide during runtime which one to use?

On your next requirement, there's no direct support for this.  There's just this Logging Errors and Warnings special category source to which you can add trace listeners so that whenever any logging failure occurs, the trace listener/s configured in that category will be used to log the exception which occurred while logging.  The original log entry will also be included in the logged message.  Currently, the option you have so as to be able to implement the behavior you want is by creating a custom trace listener.

 

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

Nov 25, 2010 at 3:52 AM

Thanks for the reply.

I'm going to create a custom database trace listener. Because i want to store some more details to the error log table.
I will pass the other parameters in the ExtendedProperties as a Dictionary object.
Can you please make me clear for these questions
1) Where should i create custom database trace listener class? In Ent Lib or in my own class library.
2) If it is in Ent Lib side then how can combile thise class? Plese provide me any sample. I'm beginner in this
3) Can we pass the connection string through this ExtendedProperties (as Dictionary object)?

Nov 25, 2010 at 4:39 AM

You'll create it in your own class library.  It is a means of extending enterprise library so you need not modify the source code or rebuild it.  On your third question, yes you can but I might be missing something in your question.  Where do you plan to do the passing of the connection string? 

 

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

Nov 25, 2010 at 5:00 AM

Thanks for your reply.

I thought,  custom database trace listener class will be in enterprise library. and i need to pass the exception details and connection string to that TraceData method by the following way.

LogEntry logEntry = new LogEntry();
logEntry.EventId = 100;
logEntry.Priority = 2;
logEntry.Message = "Informational message";
logEntry.Categories.Add("Trace");
logEntry.Categories.Add("UI Events");
logEntry.ExtendedProperties = new Dictionary<string, object>();
logEntry.ExtendedProperties.Add("Customparamkey", "CustomparamkeyValue");
logEntry.ExtendedProperties.Add("ConnStrKey", "ConnStrValue");
LogWriter myLogWriter = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
myLogWriter.Write(logEntry);

the above code i will have it in my class library. from this class library i need to write the log to DB and event log by using Ent Lib.

Can you please tell the steps i should follow to do this Task.

 

Nov 25, 2010 at 5:25 AM

I'm quite confused, why are you manually doing the logging codes when you can use a LoggingExceptionHandler to log your exceptions?  If you would use your custom database trace listener with the LoggingExceptionHandler, then the way you could pass the connection string and other additional information to the custom database trace listener is to add those details in the exceptions .Data property.

try
{
        //some code that you're expecting to throw error
}
catch(Exception ex)
{
      ex.Data.Add("connString", connectionString);
      bool rethrow = exceptionManager.HandleException(ex, "ExceptionPolicy");
}

With this, when it goes through LoggingExceptionHandler the exception object will be converted to a LogEntry object.  The Exception.Data property then willl be mapped to the LogEntry.ExtendedProperties.  So as you can see, you need not do anything special, just make sure to add the details you want before passing the exception in the HandleException method. 

Does this answer your question?

 

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


Nov 25, 2010 at 5:42 AM

By the way, I have here a sample custom database trace listener.  If you want a copy, email me at entlib.support@avanade.com

 

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

Nov 25, 2010 at 6:11 AM

Thanks for the reply.

Yes i got understand bit now.

Here is my scanario
I have to create class library to handle exceptions. From the class library only i should use Enterprise Library to logging the exceptions by the following way.
1) First, store the exception to the DB using custom database trace listener.
2) If, any issue/error in item 1 then i should write both errors (original exception and current exception) to event log.

Here i'm writing the steps to do these tasks. Please correct me if i'm worng

I will create my own class library, and i have my own exp handling method with the parameters of exception details from the application.
For the step 1, I will create custom database trace listener by adding another class to the class library. Here is the code

<ConfigurationElementType(GetType(CustomTraceListener))> _
Public Class DebugTraceListener
    Inherits CustomTraceListener

    Public Overrides Sub TraceData(ByVal eventCache As TraceEventCache, ByVal source As String, _
          ByVal eventType As TraceEventType, ByVal id As Integer, ByVal data As Object)
 'I will get the connection string by data.<connstr>
 'Also i will get the extra parameters by data.<paramname>
 'execute the SProc by passing necessary parameters

    End Sub

    Public Overrides Sub Write(ByVal message As String)
        'If exception in sotring details i should write to event log - step 2
 ExceptionPolicy.HandleException(ex, "ExceptionPolicy") ' write event log by providing the policy name 
    End Sub

    Public Overrides Sub WriteLine(ByVal message As String)
        Debug.WriteLine(message)
    End Sub

End Class

Then step 2 will be done from the above method Write()
for this i have to create exception policy logging handler (as per my first post of this discussion).

Can you please tell me whether i'm doing on the correct way.
Correct me if i'm worng anywhere.

 

Nov 25, 2010 at 6:18 AM

Thanks for your support.

Yeah it would be better if you send me the sample. But. I can't access the personal mail now. Official mail not yet been creatred since i'm joined newly.. Any way you send the sample to this mail id - yogaraj_net@hotmail.com. I will check later today.

In the mean while i would like to get the reply from you for my previous post.

Nov 25, 2010 at 6:31 AM

With the code you posted, your Write methods won't actually get called.  When you call logWriter.Write(...), it actually executes the TraceData method. So normally, in the TraceData method, you'll check if the data parameter is of type LogEntry or string, if it's string, you pass it in the Write(string) method.  If it's a LogEntry object, you pass it in the Write(obj) method.   So it's actually in the Write methods where you write code to execute the stored procedure.  I'll be sending the sample custom database trace listener so you'll have a better picture of what I'm saying.

I also recommend not to call HandleException here since it might cause infinite loop in cases when the exception policy you're using also uses the same trace listener.  Just enclose your code in a try catch and use the Logging API to log the exception which occurred. 

 

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

Nov 25, 2010 at 6:50 AM

Thanks for your reply.

I will check the sample which ll u send.

Can you please suggest me how can achieve the following

1) store excetion details to CB (custom database trace listener)

2) If any exception in step 1 write both excetions to event log.

Please provide me the procdure.

 

Nov 25, 2010 at 7:16 AM

Ok, modifying a bit the code you posted above:

<ConfigurationElementType(GetType(CustomTraceListener))> _
Public Class DebugTraceListener
    Inherits CustomTraceListener
    Public Overrides Sub TraceData(ByVal eventCache As TraceEventCache, ByVal source As String, _
          ByVal eventType As TraceEventType, ByVal id As Integer, ByVal data As Object)
 'I will get the connection string by data.<connstr>
 'Also i will get the extra parameters by data.<paramname>
 'execute the SProc by passing necessary parameters
    End Sub
  Public Overrides Sub Write(ByRef data As Object)
        Try
          'Dim logEntry = data as LogEntry
        'exec stored procedure using properties from the logEntry object including the connection string and other extra parameters in the ExtendedProperties
        Catch
           Dim logWriter = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>()
           logWriter.Write(ex.Message, preferredCategory)
    End Sub

    Public Overrides Sub Write(ByVal message As String)
           Try
        'exec stored procedure using message parameter as value for Message stored proc parameter, decide what values to use for the other parameters 
           Catch
           Dim logWriter = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>()
           logWriter.Write(ex.Message, preferredCategory)
    End Sub

End Class

My sample which I sent to you also includes script for creating the necesary database objects so all  you need is to run it.  You may want to check it out first, it might be able to answer the rest of your questions.

 

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

Nov 25, 2010 at 7:37 AM

Hi Sarah,

Thanks for your support.

I will check it out and implement from my side. Then i get back to you if have any quries.

Yogaraj

Nov 26, 2010 at 1:36 AM

Hi sarah,

I have tried as per your instruction. I need some clarification from you.

I have created the DatabaseCutomTraceListener class.

when i run my application getting the following error message on the line Logger.Write(log)

 

Error Message:- Invalid TraceListenerData type in configuration 'listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=4.1.0.0, Culture=neutral, PublicKeyToken=null

Should i need to configure anything about CustomTraceListener in Enterprise Library configuration tool?

Or i can directly include the config details in my project app.config.

Please send me the steps i should follow.

Nov 26, 2010 at 1:55 AM

How are you editing the config file?  The version of the assembly you referred to in the config file is the unsigned one, the one from EntLibSrc\bin folder.   I think you meant to use the strongly named ones, the one from entlib's installation folder in Program Files\Microsoft Enterprise Library {version Number}\bin.   What version are you using exactly? 

 

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

Nov 26, 2010 at 3:01 AM

Are you asking about the enterprise library version? If so, I'm using version 4.1.

C:\Program Files\Microsoft Enterprise Library 4.1 - October 2008\Bin

Nov 26, 2010 at 4:21 AM

You're probably editing the configuration file using the configuration tool from EntLib41Src\bin folder.  See in the error message, it's saying that the listerDataType

Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database, Version=4.1.0.0, Culture=neutral, PublicKeyToken=null

is invalid.  If you used the configuration tool integrated with Visual Studio (meaning the EntLibConfig.exe from C:\Program Files\Microsoft Enterprise Library 4.1 - October 2008\Bin), then the PublickKeyToken attribute shouldn't be null, it should have a value.

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

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

Nov 26, 2010 at 4:52 AM

Thanks for your reply.

So, Now i should edit the configuration file by using EntLibConfig tool under "C:\Program Files\Microsoft Enterprise Library 4.1 - October 2008\Bin".

What are the steps i need to follow. I have created the DatabaseCutomTraceListener class already.

How should i configure the custom trace listner in EntLibConfig tool.

still i'm not cleared on this... Please provide me the steps.

 

Nov 26, 2010 at 5:20 AM

"So, Now i should edit the configuration file by using EntLibConfig tool under "C:\Program Files\Microsoft Enterprise Library 4.1 - October 2008\Bin".  What are the steps i need to follow. I have created the DatabaseCutomTraceListener class already."

 - Right click on your config file and select Edit Enterprise Library Configuration.

"How should i configure the custom trace listner in EntLibConfig tool."

Did you create it to be fully integrated with the config tool meaning you created a new class and specified it as the ConfigurationElementType for your custom trace listener?  Of did you simply decorated your custom database trace listener with[ConfigurationElementType(typeof(CustomTraceListenerData)]?  If it's the latter, then you simply need to add it by right clicking on the Trace Listeners node, select New and click Custom Trace Listener.  The properties for a custom trace listener appears then.  Go to the Type property and click on the Ellipsis button.  You will be then locate the assembly where your custom trace listener is. 

On the other hand, if you're using full integration with the config tool, you need to deploy your custom trace listener assembly in C:\Program Files\Microsoft Enterprise Library 4.1 - October 2008\Bin directory.  Once you have it there, your custom trace listener should appear in the list when you open your config in the configuration tool, right click on the Trace Listeners node and select New.

Which one of this did you create?

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

Nov 26, 2010 at 7:20 AM

Thanks for the reply.

I guess i have creatred the first one, i have created the new class in my application (custom database trace listener with[ConfigurationElementType(typeof(CustomTraceListenerData)]).

Then from the enterprise library configuration tool i have opened my own app.config file(File >> Open Application).

Then added the Logging Application Block - Trace Listeers - Custom Trace Listner.

This is my class:-

Namespace CustomDatabaseLogging
    <ConfigurationElementType(GetType(CustomTraceListenerData))> _
    Public Class DatabaseCutomTraceListener
        Inherits CustomTraceListener
        Public Overrides Sub TraceData(ByVal eventCache As TraceEventCache, ByVal source As String, _
          ByVal eventType As TraceEventType, ByVal id As Integer, ByVal data As Object)
            If (TypeOf data Is LogEntry) And Me.Formatter IsNot Nothing Then
                WriteLine(Me.Formatter.Format(DirectCast(data, LogEntry)))
            Else
                WriteLine(data.ToString())
            End If
        End Sub
        Public Overrides Sub Write(ByVal message As String)
            Throw New Exception("The method or operation is not implemented.")
        End Sub
        Public Overrides Sub Write(ByVal o As [Object])
            Dim log As LogEntry = TryCast(o, LogEntry)
            Dim db As Database = DatabaseFactory.CreateDatabase()

            Dim cmd As DbCommand = db.GetStoredProcCommand("WriteLog")

            db.AddInParameter(cmd, "eventID", DbType.Int32, log.EventId)
            db.AddInParameter(cmd, "priority", DbType.Int32, log.Priority)
            db.AddParameter(cmd, "severity", DbType.[String], 32, ParameterDirection.Input, False, _
             0, 0, Nothing, DataRowVersion.[Default], log.Severity.ToString())
            db.AddParameter(cmd, "title", DbType.[String], 256, ParameterDirection.Input, False, _
             0, 0, Nothing, DataRowVersion.[Default], log.Title)
            db.AddInParameter(cmd, "timestamp", DbType.DateTime, log.TimeStamp)
            db.AddParameter(cmd, "machineName", DbType.[String], 32, ParameterDirection.Input, False, _
             0, 0, Nothing, DataRowVersion.[Default], log.MachineName)
            db.AddParameter(cmd, "AppDomainName", DbType.[String], 512, ParameterDirection.Input, False, _
             0, 0, Nothing, DataRowVersion.[Default], log.AppDomainName)
            db.AddParameter(cmd, "ProcessID", DbType.[String], 256, ParameterDirection.Input, False, _
             0, 0, Nothing, DataRowVersion.[Default], log.ProcessId)
            db.AddParameter(cmd, "ProcessName", DbType.[String], 512, ParameterDirection.Input, False, _
             0, 0, Nothing, DataRowVersion.[Default], log.ProcessName)
            db.AddParameter(cmd, "ThreadName", DbType.[String], 512, ParameterDirection.Input, False, _
             0, 0, Nothing, DataRowVersion.[Default], log.ManagedThreadName)
            db.AddParameter(cmd, "Win32ThreadId", DbType.[String], 128, ParameterDirection.Input, False, _
             0, 0, Nothing, DataRowVersion.[Default], log.Win32ThreadId)
            db.AddParameter(cmd, "message", DbType.[String], 1500, ParameterDirection.Input, False, _
             0, 0, Nothing, DataRowVersion.[Default], log.Message)
            db.AddInParameter(cmd, "formattedmessage", DbType.[String], log.Message)

            Dim dictionary As IDictionary(Of [String], Object) = log.ExtendedProperties
            dictionary("UserName").ToString()

            db.AddInParameter(cmd, "UserName", DbType.[String], dictionary("UserName"))

            db.AddOutParameter(cmd, "LogId", DbType.Int32, 4)

            db.ExecuteNonQuery(cmd)
            Dim logId As Integer = Convert.ToInt32(cmd.Parameters(cmd.Parameters.Count - 1).Value)


            'return logId;
            'throw new Exception("The method or operation is not implemented.");
        End Sub

        Public Overrides Sub WriteLine(ByVal message As String)
            Throw New Exception("The method or operation is not implemented.")
        End Sub
    End Class
End Namespace

 *****************************************************************

In my application page_load event i worte this code:-

Dim log As New LogEntry()
        log.EventId = 100
        log.Priority = 1
        log.Title = "Main"
        log.Message = "Main Method Executed"
        log.Categories.Add("General")
        Dim dictionary As Dictionary(Of [String], [Object]) = New Dictionary(Of String, Object)()

        dictionary.Add("UserName", "admin")

        Logger.Write(log)

*********************************

My scanario is

I need to store the exception details to the database with my own extra parameters (created by, module name and page name.. etc).

I have added the columns in the tables also i modified the stored procedure to our need.

Did i followed the correct way. Plese suggest me if i'm doing wrongly.

Note:- Now the Logger.Write(log) is executing properly (No error occur). but none of the method in the class(DatabaseCutomTraceListener) is firing (alreay put the break points).

Nov 26, 2010 at 7:24 AM

Forgot to ask you one thing in the previous post..

when i open the custom trace lintener - type property in the tool i didnt find any assembly of my application.

how to load the assembly. i selected the Load from file option.. But i'm not sure what i have to select..

 

 

Nov 26, 2010 at 7:31 AM

Just locate where is your assembly.  If you defined your custom trace listener inside a class library project named CustomProvider, then go to that project directory and navigate to the bin\Debug folder.  CustomProvider\bin\debug and select CustomProvider.dll.  It should then display your custom database trace listener after clicking on it.  If it doesn't, close and reopen Visual Studio and try it again.

So if you failed to do this in the first place, then maybe that's the reason why your custom database trace listener isn't firing.  By the way, in your code, did you intentionally have it throw an exception ("The method or operation is not implemented')?  If yes, and if you're expecting your application to encounter that exception, that won't happen because exceptions which occur while performing logging operation are being swallowed and handled by the Logging Application Block internally.

 

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

Nov 26, 2010 at 8:01 AM

Thanks for the reply.

If any exception in my application, first i need to write it to DB.

Then, If i get any exception on database logging, i should write the error details (both original error and this current error)to event log by using enterprise library.

this is what i should do. i'm struggling to do this task from 2 days since i'm very new to enterprise library. Now i got some idea about ent lib. but still couldn't able to complete this task

help me out for this.

 

 

Nov 26, 2010 at 8:07 AM

Ok, let's do this step by step.  So you have created your custom database trace listener.  I've already discussed and gave a sample of the logic of writing to database so I'll assume your logic in your custom database trace listener is correct.  That's up to you.

Now, were you able to successfully configure it in your configuration file?

 

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

Nov 26, 2010 at 9:05 AM

Thanks for your reply.

Yes, now i can be able to configure the custom databse trace listner by selecting dll in the property type.

this added in my app.config also.

 <listeners>
      <add listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.CustomTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"         traceOutputOptions="None" filter="All" type="AppErrorHandler.CustomDatabaseLogging.DatabaseCutomTraceListener, AppErrorHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"      name="Custom Trace Listener" initializeData="" />
      <add source="Enterprise Library Logging" formatter="Text Formatter"
        log="Application" machineName="" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        traceOutputOptions="None" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        name="Formatted EventLog TraceListener" />
    </listeners> 

I have one doubt on this. is there anyother way (instead of having in the configuration file) to pass the DB connection string.

I will let you know the DB logging status once i finished my testing.

Can you please guide me the next step. how to store in to event log by using Ent Lib if we get exception in DB logging.

 

 

 

 

Nov 28, 2010 at 6:18 AM
Edited Nov 29, 2010 at 2:02 PM

Hi Sarah,

Can you please assist me to complete this taks. I'm looking forward to your reply.

Thanks,
Yogaraj

Nov 30, 2010 at 12:08 AM

If you add a trace listener under the Logging Errors and Warnings special category, any exception which occurred while performing logging will be automatically logged using that trace listener.  However, in your other thread, you said that you want to be able to continue logging using the other trace listener as well as log the exception that occurred while logging to the database.  So my question is, does my first statement here would suffice or are you sticking to your requirement on continue logging the original message and the exception?  If it's the latter, then tell me what is it that you are unable  to follow in the steps which I mentioned in our other discussion thread.

 

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

Nov 30, 2010 at 12:38 AM

Thanks for your reply.

Is it possible to store the both exception details (original exception and exception in DB logging) in event log.
If possible how can do the configuration for this.
This is what i did so for,
I have created the DatabaseCustomTraceListener.vb class as we discussed earlier.
Opened the app.config file in Enterprise Library Configuration.
Added Logging Application Block >> Added custom trace listener under Trace Listeners >> selected the dll under type property.
Added the trace listener reference under Special SOurces >> logging errors & warnings

Still none of the event is firing in the DatabaseCustomTraceListener.vb class after the line Logger.Write(log).
What will be the problem?
here is the code i have wrote on the page load (win app) for testing

   Dim log As New LogEntry()
        log.EventId = 100
        log.Priority = 1
        log.Title = "Main"
        log.Message = "Main Method Executed"
        log.Categories.Add("General")
        Dim dictionary As Dictionary(Of [String], [Object]) = New Dictionary(Of String, Object)()
        dictionary.Add("UserName", "admin")
        Logger.Write(log)

Should i need to change anything in the above code as per the configuration i did?

 

Nov 30, 2010 at 12:54 AM

Don't add the custom database trace listener as trace listener reference under the Logging Errors and Warnings special source.  You should use the Formatted Event Log Trace Listener.  Your custom database trace listener should be added under the General logging category since you added the string "General" in your log entry's Categories property (log.Categories.Add("General")). 

 If still there's no log written in your database after doing this, check your event log, it should have a logged error message containing details as to why logging to the database failed.

 

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

Nov 30, 2010 at 1:11 AM
Edited Nov 30, 2010 at 1:23 AM

Thanks for the reply.

Now the method TraceData() is firing properly. this is the method

  Public Overrides Sub TraceData(ByVal eventCache As TraceEventCache, ByVal source As String, _
          ByVal eventType As TraceEventType, ByVal id As Integer, ByVal data As Object)
            If (TypeOf data Is LogEntry) And Me.Formatter IsNot Nothing Then
                WriteLine(Me.Formatter.Format(DirectCast(data, LogEntry)))
            Else
                WriteLine(data.ToString())
            End If
        End Sub

here the condition (TypeOf data Is LogEntry) is goes to else part and the following content is there is data.ToString().

Timestamp: 11/30/2010 2:06:54 AM Message: Main Method Executed Category: General Priority: 1 EventId: 100 Severity: Information Title:Main Machine: WPMYD0000797-1 App Domain: EntLibLoggingApp.vshost.exe ProcessId: 11848 Process Name: C:\Yogaraj\EntLibLoggingApp\EntLibLoggingApp\bin\Debug\EntLibLoggingApp.vshost.exe Thread Name:  Win32 ThreadId:13424 Extended Properties: "

My DB logging code is under this method - Public Overrides Sub Write(ByVal o As [Object])
when this method suppose to get fire? still this method is not firing.

any thing i missed?

Nov 30, 2010 at 1:18 AM

It's really up to you.  The logging entry point for your custom trace listener is actually the TraceData method.  When you call Logger.Write or logWriter.Write method, it eventually calls the TraceData method.  It's up to you to call whichever overload Write method you want to call from there.  If you only provided implementation for Write(ByVal o as Object), then you should be calling it rather than the WriteLine methods.

 

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

Nov 30, 2010 at 1:31 AM

Thanks for the reply.

I got understand now. I have a question, this argument "ByVal data As Object" should be a LogEntry object right?
then only i can get all the values like EventId, priority, ExtendedProperties etc..
I'm not clear on this. please make me clear.

also i checked the event logs in event viewer. so for no logs are there. i checked under Event Viewer >> Application  and also in Event Viewer >> System.

What will be the problem?

Nov 30, 2010 at 1:45 AM

The parameter is of type object, you just need to cast it back to type LogEntry inside the method

Dim logEntry = data As LogEntry

As for your other question, you didn't get any log in the event viewer because there was no error while logging.  If you need to log the original message to the event viewer as welll, then you need to add it also under the General category.

 

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

Nov 30, 2010 at 2:00 AM

Thanks for your fast reply.

Now, I can extract all the parameters and trying to store it to the database.
under TraceData method i'm using my own DB insertion code (already created my own SPROC and talbe).
is this the correct way i'm doing. because, what is the rold of enterprise library here. i'm bit confused on this.

Next is i have given wrong connection string and got exception while debugging the code. but, still i couldn't see the event log entry. where i have to check this?

As per you instruction i need to add one more trace listener reference (Formatted EventLog TraceListener) under the General category to log the original exception. am i correct on this?
If so, how can i log my ExtendedProperties in event log. should i need to write another method for this?

Please make me clear for the above questions.

Nov 30, 2010 at 2:40 AM

Putting your DB insertion code in TraceData method is fine, I would just prefer it to be on the Write method so as to clearly separate functionalities in the different methods. 

As for logging the ExtendProperties in the event log, there's no need to write any special code for this.  Just make sure that the associated formatter of your event log trace listener has the ExtendedProperties token  in its Template property

Extended Properties: {dictionary({key} - {value}{newline})}

Let me also make it clear:

the "original" message is the LogEntry which you passed in the call to Logger.Write.  On the other hand, the exception I'm referring to is the exception which occurred while logging to the database. 

So to log the original message to the event log, you need to add a trace listener reference  (Fromatted EventLog Trace Listener) under the General category.

If you need to log as well the exception to the event log, you need to add a trace listener reference (Formatted EventLog Trace Listener) under the Logging Errors and Warnings special category.

If on both cases you are unable to see a log being written to the event log, please post the properties of your event log trace listener.  In addition, configure a flat file trace listener under Logging Errors and Warnings instead so as to check what is the problem which causes log entries not to be written in the event log.

 

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

Nov 30, 2010 at 8:21 AM

Thanks for your reply.

I have done all those things as per your instruction
(created Fromatted EventLog Trace Listener under the General category also checked the Extended Properties in Template property. everything is fine).
still its not storing the error details to the event log.
I think the problem is with the permission. My login may not have the permission to write the event log. but, i'm not sure about this.
i will check for the event log permission with my sys admin.

i need some clarification from you
As you know i have created my own Table, SProc and method to execute the sproc for custom trace lisntener.
under TraceData method i have given my own connection string and open the sql connection and executing my Sproc.
if any issue in sql conenction or runtime error in Sproc then the exception is throwing in my code when i'm in the debug mode
(because i haven't handle any try catch block. I thought the exception should store in eventlog automatically since i have did the configuration as you said).
whether should i need to have any try catch block in this method. if yes then what should i do in catch block.
please make me clear about this.

Dec 1, 2010 at 1:44 AM

It's a good thing you ask because I forgot that if you don't handle the exception within your cusom trace listener,  the rest of the trace listeners that are in the same category as the custom trace listener is, will fail to execute.  So yes, you need to put it in the try catch block.   In the catch block, that's where you will log then the exception which occured either by using the Logging API or by making use of an exception policy with a logging handler defined for it, it's up to you which approach you would like to use.  It will longer then be processed by the trace listeners under the Logging Errors and Warnings special source. 

 

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

Dec 1, 2010 at 2:35 AM

Thanks for the reply.

I already added the Formatted EventLog TraceListener under General Category as you said before.
This should write the event log if any exception in the DB logging.
Now, what should i do it in the Catch block of my custom trace listener method.
can i able write the event log by using of Formatted EventLog TraceListener in my catch block?
if possible, what code i have to write in catch block to do the event log.

again i bit confused on this. Please make me clear.

Dec 1, 2010 at 2:48 AM

As I've said, you can use the Logging API or the exception handling API.  What I mean was,

Option 1: Create a new category adding a referenced event log trace listener.  Call the Logger.Write inside the catch block making use of that category.

Option 2: Or you can define an exception policy in your config, set the PostHandlingAction to None and add a Logging Exception Handler to it.  Set the Category property of the Logging Exception Handler to the logging category with a referenced event log trace listener.  In the catch block, call  ExceptionPolicy.HandleException(exception, "Exception Policy") where "Exception Policy" is the name of the exception policy.

 

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

Dec 1, 2010 at 3:33 AM

Thanks for the reply.

Under Exception ploicy >> Exception >> Looging Handler >> LogCategory Property i can see only "General" category.
will it works? Because, As you know under General category i have two trace linstener reference,
one is CustomTraceListener and another is Formatted EventLog TraceListener.
Please assist me...

Dec 1, 2010 at 5:12 AM

I won't recommend that.  My suggestion is to create a new  category and add only the trace listener you want to log the error.  Imagine if your General category has your custom database trace listener and an event log trace listener and you have this code:

Logger.Write("simple message", "General");

This will then attempt to write the message "simple message" using the custom db trace listener and the event log trace listener.  If the custom db trace listener fails and in your catch block you instructed to handle the exception using the trace listeners again using the trace listeners under the "General" category.  That's a big possibility for an infinite loop. 

 So my real point is, use a category that you're sure are not being used for any other reason other than logging exceptions occuring in your custom trace listener.

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

Dec 1, 2010 at 7:28 AM

Thanks for the suggestion.

I deleted the Formatted EventLog TraceListener under the General category.
I have created the exception policy and Logging Handler, and i have created the new category for "ExceptionEventLog"  then added the Formatted EventLog TraceListener for this category.
in my catch block i have written this code ExceptionPolicy.HandleException(ex,"MyPolicy")
Now, this should write to event log if any exception in customtracedata method right? - is this correct way?
i debug the code and its works fine. but i couldn't check the event log in event viewer because of access permission as i told you before.

one more doubt , event log trace listener will write the extended prperties also right? (As per your instruction i checked the template prperty already, it have extended property)

 

Dec 2, 2010 at 12:17 AM

Yes,  those are all correct.

 

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

Dec 3, 2010 at 9:06 AM

Hi I'm getting this error now..

on this line ExceptionPolicy.HandleException(ex,"MyPolicy")

The current build operation (build key Build Key[Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicyImpl, MyPolicy]) failed: Object reference not set to an instance of an object. (Strategy type ConfiguredObjectStrategy, index 2)

What will be the problem?

Dec 6, 2010 at 2:35 AM

 

This thread is really quite a very long thread to follow :-)

It looks like the Exception block application code could not able to read thru your configuration. With this, here some details that I want to be clear with;

1. Where does your Exception Block app code lies?

2. If from another class library project, does your Application Project has reference from the said class library project?

3. Could you post your configuration here for us to have further investigation.

4. Also kindly post the full exception encountered.

Thanks,

 

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

Dec 6, 2010 at 11:24 PM

I think you have your config defined in the class library project instead of the executable project.  If this is the case, then see how to get this work in this thread.

By the way, please create a new discussion thread for each different topic.  As Gino had pointed out, this is quite a very long thread.  It would be preferrable to have a single topic or related topics only on a thread so other members of the community would be able to easily follow the discussion.

 

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