Skip to content

Instantly share code, notes, and snippets.

@Bio2hazard
Last active March 3, 2017 21:00
Show Gist options
  • Save Bio2hazard/35628ab424291a4aba999dbbd1fa8598 to your computer and use it in GitHub Desktop.
Save Bio2hazard/35628ab424291a4aba999dbbd1fa8598 to your computer and use it in GitHub Desktop.
Raygun integration for webjobs
public static class RaygunExceptionHandler
{
private static readonly RaygunClient _client;
static RaygunExceptionHandler()
{
_client = new RaygunClient("your_apikey");
_client.AddWrapperExceptions(typeof(FunctionInvocationException));
}
public static void Process(TraceFilter filter)
{
var events = filter.GetEvents().Where(e => e.Exception != null);
foreach (var traceEvent in events)
{
_client.Send(traceEvent.Exception);
}
}
}
Tested on 3/3/2017 with following packages:
Microsoft.Azure.WebJobs version 2.0.0
Mindscape.Raygun4Net version 5.4.1
The old solution outlined at https://raygun.com/blog/2015/02/setting-raygun-azure-webjobs/ does not work because the Function Executor of the Azure Webjobs catches and handles exceptions, so they never bubble up as a unhandled exception.
The solution is to use the Web Jobs trace module, which allows for registering a custom exception handler.
For this, we create a static ExceptionHandler class that will process exceptions for us.
The Program.cs is the default file created from adding a new web job project. Only the code between // -- Raygun Exception Handling BEGIN and // -- Raygun Exception Handling END was added.
I added a barebones example and a extended example that collects more useful information.
/// <summary>
/// Captures and sends exceptions to Raygun for reporting and analysis.
/// </summary>
public static class RaygunExceptionHandler
{
private static readonly RaygunClient _client;
static RaygunExceptionHandler()
{
_client = new RaygunClient("your_apikey");
_client.AddWrapperExceptions(typeof(FunctionInvocationException));
}
/// <summary>
/// Process Web Job Function Invocation Exceptions
/// </summary>
/// <param name="filter">The <see cref="TraceFilter"/> containing information about the exception.</param>
public static void Process(TraceFilter filter)
{
// Get Web Job scm Host URI: yoursite.scm.azurewebsites.net
var httpHost = Environment.GetEnvironmentVariable("HTTP_HOST");
var events = filter.GetEvents().Where(e => e.Exception != null);
foreach (var traceEvent in events)
{
var tags = new List<string>();
// Add all trace properties to custom data
var customData = traceEvent.Properties.ToDictionary(traceEventProperty => traceEventProperty.Key, traceEventProperty => traceEventProperty.Value);
// If the FunctionInvocationId is available to us, we can use it to build a clickable link using the http host
if (traceEvent.Properties.ContainsKey("MS_FunctionInvocationId") && !string.IsNullOrEmpty(httpHost))
{
var functionInvocationId = traceEvent.Properties["MS_FunctionInvocationId"];
customData["Dashboard URL"] = $"https://{httpHost}/azurejobs/#/functions/invocations/{functionInvocationId}";
}
// If the FunctionDescriptor is available to us, we can use it to tag the executed function in raygun
if (traceEvent.Properties.ContainsKey("MS_FunctionDescriptor"))
{
var functionDescriptor = (FunctionDescriptor)traceEvent.Properties["MS_FunctionDescriptor"];
tags.Add(functionDescriptor.ShortName);
}
_client.Send(traceEvent.Exception, tags, customData);
}
}
}
// To learn more about Microsoft Azure WebJobs SDK, please see http://go.microsoft.com/fwlink/?LinkID=320976
class Program
{
// Please set the following connection strings in app.config for this WebJob to run:
// AzureWebJobsDashboard and AzureWebJobsStorage
static void Main()
{
var config = new JobHostConfiguration();
// -- Raygun Exception Handling BEGIN
var traceMonitor = new TraceMonitor()
.Filter(p => p.Exception != null, "Exception Handler")
.Subscribe(RaygunExceptionHandler.Process);
config.Tracing.Tracers.Add(traceMonitor);
// -- Raygun Exception Handling END
var host = new JobHost(config);
host.RunAndBlock();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment