Enterprise library 4.1 Exception handling

Topics: Exception Handling Application Block, Logging Application Block
Nov 29, 2010 at 3:59 PM

I want to do the excetion handling for my web application using enterprise library 4.1.
I should create class library for the exception handling.
In my class library i need to store the exception details to the database.
If any issue in the database logging then i need to log the exception in windows event log.
Now i need few clarifications
1) Can i do these two tasks in same class library?
2) If yes, then can i have the single app.config file to have the both (DB logging and event log)configuration details?
3) I have created the custom trace listener class (i have my own SP and table in the DB) in my class library for DB logging. Now how do i configure the event log if any exception in this DB logging

Please help to provide the steps to do this.

Nov 30, 2010 at 1:30 AM
Edited Nov 30, 2010 at 3:54 AM

Yes, you can do it in a class library and you can have as ingle configuration file.  Keep in mind that the configuration file must be in the host/executable project as class libraries don't own configuration files.

On your third question, you can configure any exception which occurs while logging to be logged in the event log by adding a Formatted Event Log Trace Listener under the Logging Errors and Warnings special category.  Take note that this applies to all exception during logging and you can't configure it to only log exception when a specific trace listener fails.

 

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

Nov 30, 2010 at 3:46 AM

Ok. But, we can add the app.config file in the class libraries right? If it not works then where can i have my cofig file.

I should create the exception handling in my class library(dll). i can't have this configuration details in my web application.

How can i proceed. As of now, i'm testing with windows application. Once everything is ok then i planned to move it to class library.

 

Nov 30, 2010 at 3:53 AM

You could use any configuration file but you need an extra step so as to instruct the EntLib API to use that config file.  You can create an instance of FileConfigurationSource passing the path to the configuration file you want to use and make use of the corresponding factory class for the application block you're using.  In the case of the Logging Application Block, here's the sample code:

IConfigurationSource configSource = new FileConfigurationSource("logging.config");
LogWriterFactory factory = new LogWriterFactory(configSource);
LogWriter logWriter = factory.Create();
logWriter.Write(logEntryObject);

 

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

Nov 30, 2010 at 9:50 AM

Thanks for the reply.

"but you need an extra step so as to instruct the EntLib API to use that config file" - Can you please explain this. i'm not aware of this.

Also i'm not sure about your code sample where should i use that and why should we need this code.

Please explain.

Here is my configuration file code.

<configuration>
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <loggingConfiguration name="Logging Application Block" tracingEnabled="true"
    defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
    <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="EntLibLoggingApp.CustomDatabaseLogging.DatabaseCutomTraceListener, EntLibLoggingApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
        name="INGCPFCustomTraceListener" 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>
    <formatters>
      <add template="Timestamp: {timestamp}&#xD;&#xA;Message: {message}&#xD;&#xA;Category: {category}&#xD;&#xA;Priority: {priority}&#xD;&#xA;EventId: {eventid}&#xD;&#xA;Severity: {severity}&#xD;&#xA;Title:{title}&#xD;&#xA;Machine: {machine}&#xD;&#xA;Application Domain: {appDomain}&#xD;&#xA;Process Id: {processId}&#xD;&#xA;Process Name: {processName}&#xD;&#xA;Win32 Thread Id: {win32ThreadId}&#xD;&#xA;Thread Name: {threadName}&#xD;&#xA;Extended Properties: {dictionary({key} - {value}&#xD;&#xA;)}"
        type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        name="Text Formatter" />
    </formatters>
    <categorySources>
      <add switchValue="All" name="General">
        <listeners>
          <add name="INGCPFCustomTraceListener" />
          <add name="Formatted EventLog TraceListener" />
        </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="Formatted EventLog TraceListener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>
  <system.diagnostics>
    <sources>
      <!-- This section defines the logging configuration for My.Application.Log -->
      <source name="DefaultSource" switchName="DefaultSwitch">
        <listeners>
          <add name="FileLog" />
          <!-- Uncomment the below section to write to the Application Event Log -->
          <!--<add name="EventLog"/>-->
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="DefaultSwitch" value="Information" />
    </switches>
    <sharedListeners>
      <add name="FileLog" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" initializeData="FileLogWriter" />
      <!-- Uncomment the below section and replace APPLICATION_NAME with the name of your application to write to the Application Event Log -->
      <!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
    </sharedListeners>
  </system.diagnostics>
</configuration>

Dec 1, 2010 at 1:08 AM

You  need to add that extra step because class libraries read their configuration from the configuration file of the executable project.  For example, in the case if you have a console application referencing a class library, any code in your class library which involves reading a configuration file actually reads the configuration file of your console application even if you have an app.config in that class library project.  

So, for you to be able to utilize the loggingConfiguration section defined in the configuration file you add in your class library, you need to make use of the code I posted .

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

Dec 1, 2010 at 2:55 AM

Thanks for the details.

I got understand now. My scanario is, I have to create a class library and add this dll to my application.

the following code i will write in my class library method.

IConfigurationSource configSource = new FileConfigurationSource("logging.config");
LogWriterFactory factory = new LogWriterFactory(configSource);
LogWriter logWriter = factory.Create();
logWriter.Write(logEntryObject);

When run the executable application, FileConfigurationSource("logging.config") should look the file in my class library rather than in my executable application.
but, it seems it searching the file in my root directroy of the executable application.
should i need to copy the app.config of class library in to any of the location (may be inside the application directory)?
We are creating a dll for each application block of Ent Lib. so it seems i should have all the configuration files inside the application directory.
But, I thought once i refered the dll to my executable application it will look the (FileConfigurationSource("logging.config")) configuration file inside the class library only.

What i need to do now? Please make me clear.

 

 

 

Dec 1, 2010 at 3:04 AM

Does your logging.config gets deployed in your project's output folder?  If not, check the properties of the app.config file, set the Copy to Output Directory to Copy Always.  It should look for the file in the application directory.

 

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

Dec 1, 2010 at 4:13 AM

Hi Sarah,

I set the  Copy to Output Directory to Copy Always in my class library app.config property.
I build the class library and i can see the app.config under bin folder of this class library.
Now, I'm referencing this dll from my exceutable application but i dont see this app.config file is copying to the executable appliaction.
Again getting the same issue on the following line (The configuration file C:\Yogaraj\SampleWebApp\app.config could not be found.).
Dim configSource As IConfigurationSource = New FileConfigurationSource("app.config")

should i need to copy the app.config file manually to the executable appliaction?
if yes, then it will be difficult for us. Because, we are creating many class libraries in our application. then i should copy all config files to my executable app.

Dec 1, 2010 at 6:17 AM

If you're already referencing the .dll file, then you really need to make the file available to your application.  You can create a sub folder within the application directory and deploy all the config files you need there. 

If you're using EntLib 5.0, you're other option would be to use the Fluent Configuration API which lets you build the configuration during runtime. 

 

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

Dec 6, 2010 at 2:44 AM

Hi Sarah,

Thanks a lot for your clarifications.

I have included the config file of class library to my executable project.
I have used the following code as per your sugesstion and it works fine
IConfigurationSource configSource = new FileConfigurationSource("logging.config");
LogWriterFactory factory = new LogWriterFactory(configSource);
LogWriter logWriter = factory.Create();
logWriter.Write(logEntryObject);

For the logging the above code is working fine... but, for exception policy how can i refer the config file.

ExceptionPolicy.HandleException(ex, "MyPolicy")

the above code fails in runtime because it can't find the config file.

Hope you understand my problem.

How can i solve this?

Dec 7, 2010 at 12:20 AM
ExceptionPolicyFactory factory = new ExceptionPolicyFactory(configSource);
ExceptionPolicyImpl exceptionPolicyImpl = factory.Create(policyName);
exceptionPolicyImpl.HandleException(exception);

Just look for the corresponding factory class for each of the application block you need.

 

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