Use Raygun error tracking with your Debug and Trace code
As we all know, exception handling is critical to every applications success. It's not a matter of if something goes wrong, its how and when. However, it's one thing to trap an exception and another to get that information into an actionable format. Anyone who's looked at a mile long error log full of duplicate errors and with no contextual information will understand that well. So because we not only need to trap the errors but also understand them and the context they occurred in, there are many tools and libs out there to help. Some open source, like Log4Net and Elmah, and some directly from Microsoft like the Enterprise Library from Patterns and Practices. I've used all of those great libraries and then some, often switching over time as my needs changed. What I ultimately landed on though where the plain old Trace and Debug classes provided in System.Diagnostics of the .NET framework. This allowed me to easily add both tracing and error reporting in a similar way, while at the same time allowing me to configure several Listeners and Filters to route and process the messaging as needed. It seems (and is) really basic out of the box, but with a few modifications to a custom TraceListener, a simple Trace.TraceError.aspx) can be very powerful and packed with information. The real benefit though with using the Trace and Debug classes is that you can change who is listening per app and per situation, while your code remains the same.
So what happens when your own system isn't enough or when you need to scale across multiple platforms, even in the .NET realm? All of the sudden the prospect of getting all of your exceptions in one place becomes daunting to say the least. Then I found Raygun from the folks at Mindscape. I'm still new to the product, but from my use and implementation thus far, it's exactly what i was looking for. Put simply, its diagnostics as a service. It allows reporting exception information from nearly any code base and platform out there using a custom library or directly via their web API. It's also built for teams with support for multi-user organizations and hooks into the most popular alm and chat software like Jira, HipChat, Campfire, and others. So centralized, searchable, alerting, and actionable diagnostic messaging across platforms that your team can access from anywhere...its hard not to like.
Great! Found the service that I want to use, but now I'm faced with potentially refactoring quite a bit of code to take full advantage of Raygun for my server applications. It's not that The Raygun library for .NET is difficult to use, quite the contrary, its just proprietary. So the goal for me obviously was to explore the idea of allowing my current Trace an Debug code to feed into Raygun without any refactoring required. And as it turned out, a day or so of coding and testing, and I have this working well in both a large sale web application and a critical backend windows service application.
The library I wrote is called Raygun.Diagnostics which is open source and available on Github and Nuget. I essentially built a new custom TraceListener that overrides all trace events to build the message the way Raygun wants it, which it then sends using the Raygun .NET library. The general idea is to use the Trace.TraceError method override.aspx) that accepts
(string, params object) to stuff in the extra state and tracking information we care about. So while most standard listeners will just expect a formatted string with args, this will use that data to generate both Raygun tags and custom data to pass along with the Exception.
In this case, I'm calling TraceError with a custom message, the Exception that occurred, an IList of tags, and either a new Dictionary with the state I want to send or just simply adding that state as additional args. Now if an out of the box listener were to pick that up, like the ConsoleTraceListener.aspx), it would just ignore all params beyond the message string...no harm no foul. But to make sense of that information, the new custom trace listener picks that same message up and processes it in a way that Raygun can make the most of.
In this excerpt from the custom listener, the method is accepting the trace event information along with our custom
object and packaging it in a way that can then be transferred using the Raygun .NET client. Check out the full source here https://github.com/sirkirby/raygun.diagnostics/blob/master/src/Raygun.Diagnostics/RaygunTraceListener.cs
That's really all there is to it. I can keep my tracing code while leveraging the cool capabilities of Raygun without any refactoring required! I'm going to keep iterating on the library as needed or as issues arise but feel free to contribute as well. Issues and pull requests welcome.