Skip to main content

Integrate ELMAH with WCF and Azure

I recently integrated ELMAH (Error Logging Modules and Handlers) with our Azure application. ELMAH is an excellent error logging and reporting libary available for ASP.Net. We used ELMAH for logging all unhandled service exceptions in WCF and ASP.Net. While there is information available on internet about how to integrate these technologies, data is scattered in bits and pieces. My aim through this blog post is to details the steps required for integration.

The scenario of usage is, we wanted to log all unhandled exception thrown by our WCF service layer in a database which in our case was SQL Azure. Once done we could easily navigate to the the elmah default url to get a nice report on what errors were being generated by the application. Had it been a typical ASP.Net application, integrating ELMAH is a piece of cake. But since we were working on a Azure web deployment with SQL Azure as the backend some tweaks were necessary. Here are the things to do to get ELMAH fully functional in an Azure deployment

  1. Download Binaries : Start with downloading the binaries from the google source code repository here and add it to your solution project.
  2. Install ELMAH SQL Script: The default SQL script that is part of the download does not work directly with SQL Azure DB. I have updated the script and am adding it to the end of post.
  3. Implement IErrorHandler: Since WCF itself does not have a common\single point failure catching mechanism like ASP.Net (global.asax ApplicationError event) we need to implement one. The IErrorHandler approach is a perfect fit for this situation. Check this post for better understanding the approach. It involved
    1. Writing an implementation for IErrorHandler and IServiceBehaviour.
    2. Implementing the method ProvideFault which would log the error using ELMAH. This method is called everytime an error occurs.


    3. Add other custom code to implement the IServiceBehaviour.
    4. Since we wanted config file support we also implemented a custom BehaviorExtensionElement.
    5. The complete implementation is available as downlad at the end of the blog post.
  4. Cofigure ELMAH : ELMAH by default is configure to store errors in memory which i don't think is terribly useful. To configure SQL Server integration we need to
    1. Add configuration section declaration for ElMAH in web.config
      <configSections>
      <sectionGroup name="elmah">
      <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
      </sectionGroup>
      </configSections>

    2. Add configuration section for ELMAH. Remember to provide a valid connection string in the settings. This connectionstring value will not be user which i will detail later.
      <elmah>
      <errorLog type="ELMAHIntegration.ELMAHSQLErrorLog,ELMAHIntegration" connectionString="[Dummy Connection String]"/>
      </elmah>

    3. Note the type used in this configuration (ELMAHSQLErrorLog) is not the default type that comes with the library. I have attached code for this class too.
  5. Integrate ELMAH settings with Azure configuration : The problem with Connection string defined in web.config for an Azure deployment is that it is not consistent with Azure's own configuration . Azure uses a cscfg file to store application level settings whereas ELMAH is configured to pick connectionstring from web.config, What we want is to pick connectionstring defined in Azure cscfg file. This is where we use the magic of inheritance to change ELMAH behaviour in terms of selecting connection string.
    1. Create a class ELMAHSQLErrorLog which derives from Elmah.SQLErrorLog class and overrides its ConnectionString property.
      public override string ConnectionString
      {
      get
      {
      if (RoleEnvironment.IsAvailable)
      {
      return RoleEnvironment.GetConfigurationSettingValue(ErrorLoggerConnectionStringConfigKey);
      }
      else
      {
      return ConfigurationManager.ConnectionStrings[ErrorLoggerConnectionStringConfigKey].ConnectionString;
      }

      }
      }

    2. Reference this class in relevant section in the web.config file (See step 3)
  6. Voila !!! now ELMAH should start logging data in SQL Azure database.
Hope this post helps everyone integrate ELMAH in their WCF/Azure project. The code files mentioned in this walk through can be downloaded from this location.

Happy Coding,
Chandermani

Comments

Popular posts from this blog

Caching Images downloaded from web on Windows Phone Isolated storage

I was helping on a Windows Phone application where the requirement was to cache the images the phone downloads on the isolated storage for offline viewing.
I wanted a solution which was simple and as transparent as possible. While researching I found  someone wrote a Silverlight converter for loading images from isolated storage. Taking that as a base I created a converted which can
Load image from web (http + https), and persist it to isolated storage.In case of network connectivity issues can load the same image from isolated storage. It does that by mapping the http url to a isolated storage location.In case the network is down and the image is neither there in cache, loads a default image, passed as parameter to converter.Here is the gist for the implementation.


To use the converter
Import the name space.Declare the converter as resource.Set the Image Source Property to use this converter like this 

IIS Url Rewrite and HTTP POST data

If you play around with IIS Url Rewriting rules and try to do redirects on an HTTP POST you loose your POST data.

To make sure you get the post data you have to set the `redirectType` to `Temporary` within your rules. So the action configuration looks like this

<action redirectType="Temporary" type="Redirect" url="http://{HTTP_HOST}{REQUEST_URI}"> </action>
You may think what scenario warrant a POST request redirect. We faced one such scenario while doing SSO with a federated Identity Provider (IP)  such as Google, Azure AD. In federated authentication scenario once the user is authenticated by the IP, it redirects back to your site with claim tokens in a POST request over secure channel (https). In our case we wanted to redirect to user back http after receiving the request. But any redirects were causing loss of token. By doing a 307 (Temporary) redirect we were able to preserve the post data.