Switch Out Your Raygun API Key Depending on Web API Cloud Configuration


Raygun is an excellent tool that lets you know about more errors in your app than you would ever dare to fear were present.

Error report showing no errors

Configuration is easy: install the NuGet package, add a couple of lines to your web.config and you’re ready to go.

When done, your config file will include:

<section name="RaygunSettings"
         type="Mindscape.Raygun4Net.RaygunSettings, Mindscape.Raygun4Net"/>

and

<RaygunSettings apikey="YOUR_APP_API_KEY" />

But, what if you want to install it within something like a Web or Worker Role on Azure? With these, you have ServiceConfiguration.Local.cscfg and ServiceConfiguration.Cloud.cscfg for configuration and they don’t support custom config sections.

App Registration

When you register the Raygun handler with your app, the default code looks like this:

var config = new HttpConfiguration();
RaygunWebApiClient.Attach(config);

This uses the API key from your config file to create a RaygunWebApiClient to report on errors. But, as we already know, we don’t have a config section.

To deal with this, the RaygunWebApiClient.Attach method has an overload that lets us provide an instance of the client. So we can use this to generate a new client using our cloud settings.

var config = new HttpConfiguration();
 
// Get a reference to whatever we use to pull cloud config
var configManager = container.Resolve<IConfigurationManager>();
 
// Get the API key for this config
var raygunApiKey = configManager.GetSetting("Raygun_api_key");
 
// Overload attach with a new client
RaygunWebApiClient.Attach(config, () => new RaygunWebApiClient(raygunApiKey));

Here, we’re pulling in a config manager instance to read out cloud settings (this example is using an Autofac container, but anything could be used) and then using the key value to construct a new instance (line 10).

Then, all we have to do is add the setting to our service definition file:

<ConfigurationSettings>
    <Setting name="Raygun_api_key" />
</ConfigurationSettings>>

and then the correct values for Local

<ConfigurationSettings>
    <Setting name="Raygun_api_key" value="my-local-api-key" />
</ConfigurationSettings>

and Cloud

<ConfigurationSettings>
    <Setting name="Raygun_api_key" value="my-cloud-api-key" />
</ConfigurationSettings>

Extended Information

If we’re using something like Azure AD to manage users, we can also add the user information to the constructor.

var config = new HttpConfiguration();
 
// Get a reference to whatever we use to pull cloud config
var configManager = container.Resolve<IConfigurationManager>();
 
// Get the API key for this config
var raygunApiKey = configManager.GetSetting("Raygun_api_key");
 
// Overload attach with a new client
RaygunWebApiClient.Attach(config, () =>
{
    var client = new RaygunWebApiClient(raygunApiKey);
 
    if (ClaimsPrincipal.Current != null)
    {
        client.UserInfo = new RaygunIdentifierMessage(ClaimsPrincipal.Current.GetUserId())
        {
            FullName = ClaimsPrincipal.Current.GetUserName(),
            Email = ClaimsPrincipal.Current.GetUserEmail(),
            IsAnonymous = !ClaimsPrincipal.Current.Identity.IsAuthenticated
        };
    }
 
    return client;
});

ClaimsPrincipal Get methods (lines 16–19) are using extensions to pull through valid data using null checks; those methods don’t exist on the raw object.

One important thing to note is that the constructor is called every time an instance is required, so it’s best to keep things like config value lookups outside of the Attach method.

Now we can look on in horror as the errors start flooding in.