Logging through a HTTP proxy

You may find yourself in a situation, where your production web servers aren't allowing HTTP requests towards the public Internet. This also impacts the elmah.io client, which requires access to the URL https://api.elmah.io. A popular choice of implementing this kind of restriction nowadays, is through a HTTP proxy like squid.

Luckily the elmah.io client supports proxy configuration out of the box. Let’s look at how to configure a HTTP proxy through web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="elmah">
      <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
      <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
      <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
      <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
    </sectionGroup>
  </configSections>
  <elmah>
    <security allowRemoteAccess="false" />
    <errorLog type="Elmah.Io.ErrorLog, Elmah.Io" apiKey="..." logId="..." />
  </elmah>
  <system.net>
    <defaultProxy>
      <proxy usesystemdefault="True" proxyaddress="http://192.168.0.1:3128" bypassonlocal="False"/>
    </defaultProxy>
  </system.net>
</configuration>

The above example is of course greatly simplified.

The elmah.io client automatically picks up the defaultProxy configuration through the system.net element. defaultProxy tunnels every request from your server, including requests to elmah.io, through the proxy located on 192.18.0.1 port 3128 (or whatever IP/hostname and port you are using).

Proxies with username/password

Some proxies require a username/password. Unfortunately, the defaultProxy element doesn't support authentication. You have two ways to set this up:

Use default credentials

Make sure to set the useDefaultCredentials attribute to true:

<system.net>
  <defaultProxy useDefaultCredentials="true">
    ...
  </defaultProxy>
</system.net>

Run your web app (application pool) as a user with access to the proxy.

Implement your own proxy

Add the following class:

public class AuthenticatingProxy : IWebProxy
{
    public ICredentials Credentials
    {
        get { return new NetworkCredential("username", "password"); }
        set {}
    }

    public Uri GetProxy(Uri destination)
    {
        return new Uri("http://localhost:8888");
    }

    public bool IsBypassed(Uri host)
    {
        return false;
    }
}

Configure the new proxy in web.config:

<defaultProxy useDefaultCredentials="false">
  <module type="YourNamespace.AuthenticatingProxy, YourAssembly" />
</defaultProxy>

ASP.NET Core

ASP.NET Core websites doesn't have a web.config file. In this case, you will need to configure the proxy through code:

public void ConfigureServices(IServiceCollection services)
{
    services.AddElmahIo(options =>
    {
        options.ApiKey = "API_KEY";
        options.LogId = new Guid("LOG_ID");

        options.WebProxy = new WebProxy("localhost", 8888);
    });
    ...
}

In the example above, a proxy running on port 8888 locally, is set up using the WebProxy property of the elmah.io options.

ASP.NET Core 2.1 seems to have some problems when setting up authenticated proxies. We will update the documentation as soon as we know more.


This article was brought to you by the elmah.io team. elmah.io is the best error management system for .NET web applications. We monitor your website, alert you when errors start happening and help you fix errors fast.

See how we can help you monitor your website for crashes Monitor your website