2

I'd like to use Elmah to log errors from multiple customers' ASP.net Web Forms applications, to a central error database, each error logged with a unique application name.

I realise this can be easily set in the elmah.errorLog.applicationName attribute in web.config, but all our customers have standard web.config files, with the unique settings for each system in appSettings.config and connectionStrings.config files referenced by configSource or file attributes in web.config.

As the elmah sectionGroup in web.config doesn't allow the use of file or configSource, how can I set the applicationName for Elmah uniquely for each system?

I don't want to programmatically set the attribute in web.config, as it could be lost when the web.config is overwritten in the future.

I tried setting the ErrorLog.ApplicationName property in Global.asax.Application_Start(), like this, but the value I set was ignored.

Dim logger As Elmah.ErrorLog = Elmah.ErrorLog.GetDefault(Nothing)
logger.ApplicationName = "Testing 123"

Any advice would be much appreciated, as Elmah fits all our needs, we just need to be able to uniquely identify the errors it logs in the central error database.

Ted
  • 2,525
  • 2
  • 37
  • 54
  • 1
    You'd handle this just like anything else in web.config that changes per deployment, such as connection strings or API keys. Just make it part of your deployment process (You do have it automated right?) to insert the correct details for that deployment. – mason Apr 20 '17 at 15:07
  • There is an existing site publishing service that has been developed in house, but it can't customise the web.config per site at present, and the whole point of getting everything into external config files was to allow us to have a common web.config on every site. – Ted Apr 20 '17 at 15:20
  • 1
    Well, you can always modify your tools and processes to fulfill your needs. That's the whole point of having an in house tool right? Exact customization to your needs? Anyways, what happened when you tried to move the Elmah config to a separate file? What's preventing you there? Even if that's not something currently possible with [Elmah, it's open source](https://github.com/elmah/Elmah). You can modify to fit your needs, or submit a PR/Issue to have new features added. – mason Apr 20 '17 at 15:22
  • You're right, but it would seem a shame to have to do this just for a single Elmah attribute. (I should have mentioned) I tried to use the `file` and `configSource` attributes on Elmah, but I get `Unrecognized attribute` errors for both. Thanks for the suggestions! – Ted Apr 20 '17 at 15:28

2 Answers2

3

After spotting this SO post I've now managed to setup external config files for Elmah.

The elmah section of web.config looks like this:

  <elmah>
        <errorLog configSource="Config\Elmah\elmahErrorLog.config" />        
        <errorMail configSource="Config\Elmah\elmahErrorMail.config" />
        <errorFilter configSource="Config\Elmah\elmahErrorFilter.config" />        
        <security allowRemoteAccess="false" />
  </elmah>

The contents of which are as follows; elmahErrorLog.config:

<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ErrorLog" applicationName="My Unique Application Name" />

elmahErrorFilter.config (This config prevents email notifications for localhost requests):

<errorFilter>
  <test>
    <and>
      <equal binding="Context.Request.IsLocal" value="True" type="Boolean" />
      <regex binding="FilterSourceType.Name" pattern="mail" />
    </and>
  </test>
</errorFilter>

elmahErrorMail.config:

<errorMail from="foo"
           to="foo"
           subject="My Exception - {0}"
           async="false"           
           smtpServer="foo"
           userName="foo"
           password="foo">
</errorMail>
Community
  • 1
  • 1
Ted
  • 2,525
  • 2
  • 37
  • 54
1

If your deployment system allow individual app settings per customer, you can use error filtering in ELMAH to enrich all errors with an application name from app settings. Check out this blog post for details: Enrich ELMAH errors using error filtering hook.

In short, you dismiss all errors and log a new error including the application name from config:

void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs args)
{
    var httpContext = args.Context as HttpContext;
    if (httpContext != null)
    {
        var error = new Error(args.Exception, httpContext);
        error.ApplicationName = ConfigurationManager.AppSettings["AppName"];
        ErrorLog.GetDefault(httpContext).Log(error);
        args.Dismiss();
    }
}
ThomasArdal
  • 4,999
  • 4
  • 33
  • 73
  • This looks really useful, thanks Thomas. A couple of points though, when setting the ApplicationName here, it's added to the AllXml data for the exception, but the Application field itself isn't set. Is there any way to update this field too? Also, is there any way to add custom data to the error here? Many thanks again! – Ted Apr 21 '17 at 09:01
  • You're right, I just tried it. Application name cannot be set this way as the only property :( I think that the only option left is configure ELMAH from code. Here's an example to do it with elmah.io, but just replace Elmah.Io.ErrorLog with the log your are using: https://docs.elmah.io/configure-elmah-io-from-code/. When creating the dictionary, add a key named applicationName with the value from app settings. That should do the trick. – ThomasArdal Apr 21 '17 at 09:40